Junaid Farooq
Junaid Farooq

Reputation: 2608

find a user by model associations rails

I have a model Camera in which

belongs_to :user, :foreign_key => 'owner_id', :class_name => 'EvercamUser'

i have asscociation like this. when i do 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

i can get owner id, is there any way to create such function that , along side getting owner id, i can get the data which linked with this id for example at 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"

this user is present, what if when i do Camera.first then instead of OnwerID, how can i get the owners Name? Any help will be appreciated!

Upvotes: 2

Views: 623

Answers (2)

Richard Peck
Richard Peck

Reputation: 76774

how can i get the owners Name

You'd call the associative object on the Camera object:

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

... this will allow you to call the attributes of the child object on it: @camera.user.name or @camera.user.email, etc


Off topic, but I always include a reference to delegate for this type of issue; it avoids the law of demeter (where you're using more than one point to access data).

This would allow you to use:

#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)

To give you some context, Rails uses ActiveRecord to invoke/create objects for you.

In line with the object orientated nature of Rails, ActiveRecord is known as an ORM (Object Relationship Mapper). This basically allows you to create an object through ActiveRecord, and if it is associated to another (as Rails does with its associations), it will append the associated object onto the parent.

Thus, when you're asking about calling owner_id, you're referring to the foreign_key of the association (the database column which joins the two tables together):

enter image description here

What you need is to reference the associated object, which I've detailed above.

Upvotes: 2

Meeh
Meeh

Reputation: 2646

What about using join here?

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

Note: I'm a bit unsure if the correct parameter should be ":users" or ":evercamusers"

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

You could also add methods to your class to do this.

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

  def firstname
    self.user.firstname
  end
end

When you try to output data from Camera like this:

#<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

It won't show. But if you call the method like this, it should work:

Camera.first.firstname # "Garrett"

Also, if JSON is acceptable you could override the as_json method.

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

Then call it with

Camera.first.as_json

If you need to do it with all, simply loop it

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

Upvotes: 0

Related Questions