0

I have the following models:

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
  belongs_to :account
end

class Account < ActiveRecord::Base
  has_many :users
  has_many :spies
  has_many :public_listings, through: :spies
end

class Competitor < ActiveRecord::Base
  belongs_to :integration_platform
  belongs_to :account
  has_many :spies
end

class Spy < ActiveRecord::Base
  belongs_to :account
  belongs_to :competitor
  has_many :spy_relationships
  has_many :public_listings, through: :spy_relationships
end

class SpyRelationship < ActiveRecord::Base
  belongs_to :spy
  belongs_to :public_listing
end

class PublicListing < ActiveRecord::Base
  has_many :spy_relationships
end

I am having trouble doing two things:

1) In a controller, how can I look up all of the PublicListings associated with any given user (via their account > spies > spy relationships)?

2) As I pull the public_listings, is there any way to determine which competitor they are associated with and assign that to an attribute of the PublicListing (via spy_relationship > spy > competitor)?

Thanks

Isaac Y
  • 660
  • 1
  • 9
  • 27

2 Answers2

1

1) How can I look up all of the PublicListings associated with any given user ?

If the usage is frequent I would recommend to create and maintain a user_id in public_listing and load association.

Or use nested includes and fetch them in single query

u = User.includes({:account=>{:spies=>{:spy_relationships=>:public_listing}}}).where("id=1")

and access it as usual

pl = u.account.spies.collect{|x| x.spy_relationships}.collect{|x| x.public_listing}

2) Any way to determine which competitor they are associated with

Collect as usual

comps = pl.spy_relationships.collect{|x| x.spy}.collect{|x| x.competitor}

3) Assign that to an attribute of the PublicListing

You need to use virtual attributes. Check this link

Change you model like

   class PublicListing < ActiveRecord::Base
     attr_accessor :store
     has_many :spy_relationships
   end

   PublicListing.last.store = ## What ever you want ##
Community
  • 1
  • 1
Siva
  • 7,780
  • 6
  • 47
  • 54
  • I would definitely stay away from using `collect` statements as they're very costly on your database and not scalable whatsoever. – Trip May 29 '14 at 14:56
  • Yes, but using `includes` cuts the db retrieval cost significantly. – Siva May 29 '14 at 15:49
0

1) In a controller, how can I look up all of the PublicListings associated with any given user (via their account > spies > spy relationships)?

Just guessing, but you could add to your User model

has_many :public_listings, through: :account

Then you can do

User.find(x).public_listings

2) As I pull the public_listings, is there any way to determine which competitor they are associated with and assign that to an attribute of the PublicListing (via spy_relationship > spy > competitor)?

In your PublicListing model, add :

 has_many :spies, through: :spy_relationships
 has_many :competitors, through: :spies

Then you can do things like this..

PublicListing.find(x).competitors.where(type_of_competitor_attribute: "is_this")
Trip
  • 26,756
  • 46
  • 158
  • 277