Deep Relationships in Rails

I have several projects. These projects have users through membership.

However, these users belong to companies. The question is, how do you know which companies can access the project?

Ideally, I can make project.users.companies, but that won't work.

Is there a nice, enjoyable way to do this?

+4
source share
4 answers

The other answers seem to neglect the members you mentioned. If these are the actual objects that you have, then what you decide to do depends on the size of your tables. If they are not terribly huge, then the β€œmore OO” solution would probably look something like this:

class Project < ActiveRecord::Base has_many :memberships has_many :users, :through => :memberships def user_companies self.users.map {|user| user.companies}.flatten.uniq end end class Membership < ActiveRecord::Base belongs_to :user belongs_to :project end class User < ActiveRecord::Base has_many :memberships has_many :projects, :through => :memberships belongs_to :company end class Company < ActiveRecord::Base has_many :users end 

This may not work fine, as it extracts a lot of data from the database and then performs all the filtering in memory, but it is pretty intuitive to read. If you want to transfer all calculations to the database, I think that a good solution will most likely look something like this in the Project class:

 def user_companies Company.find_by_sql("SELECT company.* FROM companies, users, memberships WHERE companies.id = users.company_id AND users.id = memberships.user_id AND memberships.project_id = #{self.id}") end 

This is a little less clean, but will put most of the processing closer to the data, and only in three table joins should the creation of such a huge number of tuples fail that your DBMS is falling apart. It seems that

0
source

I assume you have this:

 class Project < ActiveRecord::Base has_and_belongs_to_many :users end class User < ActiveRecord::Base has_and_belongs_to_many :projects belongs_to :company end class Company < ActiveRecord::Base has_many :users end 

And you want to get project.companies. Less painful I can imagine:

 class Project < ActiveRecord::Base has_and_belongs_to_many :users def companies Company.all( :joins => {:users => :projects}, :conditions => {'projects_users.project_id' => self.id} ).uniq end end 

Pay attention to uniq at the end. It will remove duplicate companies.

+1
source

You must be able to establish relationships to allow: project.users.companies .

Associations:

 Project has_one User belongs_to Company 
0
source

I think you can do something like this.

 class Project < ActiveRecord::Base def self.companies Company.all(:conditions => { :users => { :project_id => @project.id } }, :include => :users) end end 

But some time has passed since I used these functions, so I can be rusty.

Edit: this may not work. Not sure if I got :include or :join correctly. But, as I said, I'm rusty.

0
source

Source: https://habr.com/ru/post/1303516/


All Articles