Reputation: 105
I have three tables Business, Users, and Subscriptions. The goal is to be able get the business' names associated with the user. The result should be an array of business names that the user has signed up for in subscriptions
List of Tables
Schema | Name | Type |
--------+-------------------+-------
public | businesses | table
public | subscriptions | table
public | users | table
Businesses Table
Column | Type
------------+-----------------------------
id | integer
name | character varying(255)
created_at | timestamp without time zone
updated_at | timestamp without time zone
Business Model
class Business < ActiveRecord::Base
end
Subscriptions Table
Column | Type
-------------+-----------------------------
id | integer
user_id | integer
business_id | integer
created_at | timestamp without time zone
updated_at | timestamp without time zone
Subscription Model
class Subscription < ActiveRecord::Base
belongs_to :user
belongs_to :business
end
Users Table
Column | Type
-----------------+-----------------------------
id | integer
username | character varying(255)
password_digest | character varying(255)
email | character varying(255)
created_at | timestamp without time zone
updated_at | timestamp without time zone
User Model
class User < ActiveRecord::Base
has_secure_password
has_many :subscriptions
end
Rails Console
u = User.find(1)
u.subscriptions.businesses.name
Response: undefined method `business'
Upvotes: 1
Views: 61
Reputation: 106037
Instead of doing an additional query for every single Subscription (as in Alireza's answer), you can do this with just one query using Rails' built-in includes
method:
subscriptions = u.subscriptions.includes(:business)
This will return a relation for all of the Subscriptions including their associated Businesses. Now you can get the business' names without doing an additional query:
business_names = subscriptions.map {|sub| sub.business.name }
I think you can also do this in one step using pluck
:
business_names = u.subscriptions.includes(:business).pluck("businesses.name")
I'm not certain pluck
plays nice with includes
, but it's worth a try.
Upvotes: 1
Reputation: 2691
since User has many Subscriptions, the call to u.subscriptions
returns an array of Subscriptions, therefore you need to loop through the array and call the business
association on each record. you can achieve what you need using:
business_names = u.subscriptions.map {|subscription| subscription.business.name }
Upvotes: 1