如何以一对一的关系找到对象模型?

时间:2012-11-21 05:03:34

标签: ruby-on-rails activerecord

我有两个模型用户

class User < ActiveRecord::Base
 attr_accessible :name, :provider, :uid

 # This is a class method, callable from SessionsController 
 # hence the "User." 
 def User.create_with_omniauth( auth)
   user = User.new() 
   user.provider = auth["provider"] 
   user.uid = auth["uid"] 
   user.name = auth["info"]["name"] 
   user.save 
   return user     
  end

 has_one :userprofile
end

userprofile

class Userprofile < ActiveRecord::Base
  belongs_to :user
  attr_accessible :age, :fname, :gender, :lname, :photo_url
end

我想检查是否有与用户关联的userprofile对象。如果有,请显示它。否则,请创建一个新的。

我正在尝试这个并收到错误。

def show
 @userprofile = current_user.userprofiles.all.where(:user_id => current_user.uid)
 if !@userprofile.nil? then
   @userprofile
 else
   @userprofile = Userprofile.new
 end
end
对于#

未定义的方法`userprofiles'

我尝试过查找而没有更好的结果。

3 个答案:

答案 0 :(得分:5)

您正在以错误的方式调用userprofile。你必须把它称为

@userprofile = current_user.userprofile

对于if else块,有一个更好的解决方案如下。

@userprofile = current_user.userprofile || current_user.userprofile.new

如果未创建用户配置文件,则会初始化该用户配置文件。

答案 1 :(得分:2)

user和userprofile具有一对一的关系,因此

@userprofile = current_user.userprofile

通过使用它,您可以获得current_ofile的用户配置文件

现在您的show方法看起来像

def show
 if current_user.userprofile.present?
   @userprofile = current_user.userprofile
 else
  @userprofile = current_user.build_userprofile
 end
end

更新:为什么要构建

http://edgeguides.rubyonrails.org/association_basics.html#has-one-association-reference

我们使用build_userprofile,因为它是one-to-one关系。但是假设如果它是has_many关系,那么我们使用userprofiles_build

答案 2 :(得分:1)

正如其他答案所指出的那样,您不需要.all.where(:user_id => current_user.uid)。制作这些命名关联的关键是rails可以自动处理查找所有数据库ID。

这也是使用build_userprofile方法的一个好主意,因为它会自动将新的userprofile链接到current_user。请注意,该方法不会自动保存新创建的记录,因此请确保调用save:

@userprofile = current_user.build_userprofile
@userprofile.save