通过模型关联rails找到用户

时间:2015-12-28 09:57:56

标签: ruby-on-rails activerecord

我有一个型号相机

belongs_to :user, :foreign_key => 'owner_id', :class_name => 'EvercamUser'
我有这样的联想。当我做Camera.first

#<Camera id: 6, created_at: "2013-12-12 17:30:32", updated_at: "2015-11-19 10:19:33", exid: "dublin-rememberance-floor2", owner_id: 4, is_public: true

我可以获得所有者ID,有没有办法创建这样的功能,除了获得所有者ID,我可以获得与此id链接的数据,例如在id = 4

#<EvercamUser id: 4, created_at: "2013-12-12 16:43:46", updated_at: "2015-04-16 15:23:19", firstname: "Garrett", lastname: "Heaver", username: "garrettheaver"

这个用户在场,如果当我做Camera.first然后而不是OnwerID,我怎么能得到所有者姓名? 任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:2)

  

我如何获得所有者姓名

您在Camera对象上调用关联对象

@camera = Camera.find x
@user   = @camera.user
@user.name #-> outputs name of associated user object

...这将允许您在其上调用子对象的属性:@camera.user.name@camera.user.email

偏离主题,但我总是在此类问题中提及delegate;它避免使用law of demeter(您使用多个点来访问数据)。

这将允许您使用:

#app/models/camera.rb
class Camera < ActiveRecord::Base
   belongs_to :user, foreign_key: :owner_id, class_name: 'EvercamUser'
   delegate :name, to: :user, prefix: true #-> @camera.user_name
end

@camera = Camera.find x
@camera.user_name #-> outputs the user's name on the camera object (not user object)

为了给你一些上下文,Rails使用ActiveRecord来为你调用/创建对象。

根据Rails的object orientated性质,ActiveRecord称为 ORM (对象关系映射器)。这基本上允许您通过ActiveRecord创建一个对象,如果它与另一个对象关联(如Rails与其associations一样),它会将关联的对象附加到父对象上。

因此,当您要求调用owner_id时,您指的是关联的foreign_key(将两个表连接在一起的数据库列):

enter image description here

您需要的是引用相关的对象,我已在上面详细说明。

答案 1 :(得分:0)

在这里使用join怎么样?

Camera.all.joins(:evercamusers)
Camera.where(:id => 1).joins(:users).first

注意:我有点不确定正确的参数应该是“:users”还是“:evercamusers”

http://apidock.com/rails/ActiveRecord/QueryMethods/joins

您还可以向您的班级添加方法来执行此操作。

class Camera < ActiveRecord::Base
  belongs_to :user, :foreign_key => 'owner_id', :class_name => 'EvercamUser'

  def firstname
    self.user.firstname
  end
end

当您尝试从Camera输出数据时:

#<Camera id: 6, created_at: "2013-12-12 17:30:32", updated_at: "2015-11-19 10:19:33", exid: "dublin-rememberance-floor2", owner_id: 4, is_public: true

它不会显示。但如果你这样调用这个方法,它应该可以工作:

Camera.first.firstname # "Garrett"

此外,如果JSON可以接受,您可以覆盖as_json方法。

def as_json(options={})
  { :firstname => self.user.firstname }
end

然后用

调用它
Camera.first.as_json

如果您需要全部执行此操作,只需将其循环

即可
Camera.all.each { |c| puts c.firstname }