【问题标题】:undefined method `avatar' for #<User::ActiveRecord_Relation:0x007fc328248ef0>#<User::ActiveRecord_Relation:0x007fc328248ef0> 的未定义方法 `avatar'
【发布时间】:2016-02-17 23:26:31
【问题描述】:

我正在尝试显示按名字或姓氏搜索的用户的数据。我能够显示为用户返回的所有数据(例如,如果按名字搜索用户,我可以提取与搜索用户关联的所有其他字段/数据,例如城市、州/省等)。

似乎给我错误的唯一字段是与每个用户关联的头像(个人资料照片)字段。 &lt;%= image_tag @user.avatar.url(:thumb) %&gt;

注意:我可以从其他用户页面(例如 show.html.erb)显示此字段。

我在点击搜索结果页面时遇到的错误是:

Users#index 中的 NoMethodError - 未定义的方法 `avatar' 用于# 用户::ActiveRecord_Relation:0x007fc328248ef0

_user.html.erb

<div class="card">

    <div class="columns">

        <div class="col">

  <%= image_tag @user.avatar.url(:thumb) %>


        </div>

          <div class="col">

             <div class="name">
            <%= user.firstname %> <%= user.lastname%>

    </div>
        <br>
           <b><%= user.city%>, <%= user.stateprov%></b>

</div>

        </div>

    </div>

index.html.erb

<% if @user.present? %>
  <%= render @user %>
<% else %>
  <p>There are no posts containing the term(s) <%= params[:search] %>.</p>
<% end %>

user.rb

class User < ActiveRecord::Base

def self.search(search)
    where("firstname LIKE ? OR lastname LIKE ?", "%#{search}%", "%#{search}%")
end


has_secure_password

  validates_length_of :password, :in => 6..20, :on => :create
  validates :password_confirmation, presence: true, if: -> { new_record? || changes["password"] }

has_attached_file :avatar,


 :path => ":rails_root/public/system/:attachment/:id/:basename_:style.:extension",
 :url => "/system/:attachment/:id/:basename_:style.:extension",


 :styles => {
  :thumb    => ['175x175#',  :jpg, :quality => 100],
 :preview  => ['480x480#',  :jpg, :quality => 70],
  :large    => ['600>',      :jpg, :quality => 70],
  :retina   => ['1200>',     :jpg, :quality => 30]
},
:convert_options => {
  :thumb    => '-set colorspace sRGB -strip',
 :preview  => '-set colorspace sRGB -strip',
  :large    => '-set colorspace sRGB -strip',
  :retina   => '-set colorspace sRGB -strip -sharpen 0x0.5'
}

validates_attachment :avatar,
    :presence => true,
    :size => { :in => 0..10.megabytes },
    :content_type => { :content_type => /^image\/(jpeg|png|gif|tiff)$/ }


end

users_controller.rb

class UsersController < ApplicationController

def create
  @user = User.new(user_params)
  if @user.save
    flash[:success] = "You signed up successfully"
    flash[:color] = "valid"
    redirect_to @user
  else
    flash[:notice] = "Form is invalid"
    flash[:color] = "invalid"
    render "new"
  end
end


def index
  @user = User.all
  if params[:search]
    @user = User.search(params[:search]).order("created_at DESC")
  else
    @user = User.all.order('created_at DESC')
  end
end



def show
  @user = User.find(params[:id])
end

def edit
  @user = User.find(params[:id])
end

def update
  @user = User.find(params[:id])

if @user.update_attributes(user_params)

redirect_to @user  

else

  render 'edit'
end
end


private
def user_params
  params.require(:user).permit(:firstname, :lastname, :email, :aptno, :streetaddress, :city, :country, :stateprov, :poszip, :receive_newsletters, :terms_accepted,  :password, :password_confirmation, :avatar)
end

end

【问题讨论】:

  • User.all 将返回一个集合,因此将其命名为@users 更合适。您正在尝试在集合上调用实例方法。您需要遍历集合并在单个实例上调用 avatar。

标签: ruby-on-rails ruby ruby-on-rails-4


【解决方案1】:

您正在尝试将一组用户用作单个用户。

def index
  @users = User.all
  if params[:search]
    @users = User.search(params[:search]).order("created_at DESC")
  else
    @users = User.all.order('created_at DESC')
  end
end

<% if @users.any? %>
  <%= render @users %>
<% else %>
  <p>There are no posts containing the term(s) <%= params[:search] %>.</p>
<% end %>

到目前为止,所做的更改只是为了避免开发人员混淆。然而真正的症结在于你使用@user而不是user的部分。

<%= image_tag @user.avatar.url(:thumb) %>

这里的区别在于user 是一个局部变量,rails 在渲染部分时创建。而@user 是你的错集!

所以只使用局部变量:

<%= image_tag user.avatar.url(:thumb) %>

并且在命名变量时要注意复数。

【讨论】:

【解决方案2】:

您看到此错误是因为您正在调用 Relation 对象上的方法,而不是 User 对象上的方法。尝试在您的关系对象上调用 .first ,它将返回一个 User 对象。然后,您可以在该 User 对象上调用 .avatar

看起来您在users_controller.rbindex 方法中将关系存储到@user

def index
  @user = User.all
  if params[:search]
    @user = User.search(params[:search]).order("created_at DESC")
  else
    @user = User.all.order('created_at DESC')
  end
end

在这两种情况下,您都调用.all,这将返回一个关系。您可以使用类似于User.where(criteria: &lt;unique criteria&gt;).first 的内容来获取实际的单数用户对象并将其保存到@user。 但是,正如 max 所指出的,拥有一个返回单个用户的 index 方法是没有意义的。因此,您应该将此功能映射到另一个控制器方法。

【讨论】:

  • 啊,我明白了。好的,对不起(很抱歉......)我的新手,但我将如何实现呢?例如。我将如何更改我的代码以反映这一点?
  • 拥有一个显示单个记录的索引方法仍然是零意义的。她显然是想展示一个系列。命名刚刚结束。
  • 同意,您的回答提供了比我更强大的解决方案,应该遵循。
  • 我在给你的答案中写了一个注释@max
猜你喜欢
  • 1970-01-01
  • 2016-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-17
  • 1970-01-01
相关资源
最近更新 更多