Ok, although not entirely new to RoR, myself and a colleague have been "discussing" some best practices for `find`. The scenario: - table of users - table of companies - a user can belong to multiple companies - end result is that the list will be used for a select list. So, if I want to get a list of companies that a particular user has been with in the last X time frame, which model should have the specialized `find` (because we may / may not have to do a "GROUP BY" as well). Should it be in the users model, because it''s all the companies would have the user in common? Or: Should it be in the companies model, because it will be a collection of companies? Thanks in adavance --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Woops ... I should''ve also mentioned that the example I gave is quite a high level rendition. The reason I''m not using HABTM or another associate is because there are quite a few other tables between users & companies and some extra conditions. Originally we had it all setup through associations but it was just just too dang slow so doing SQL by hand to significantly speed things up - the main reason for this is because of the a GROUP BY, ORDER BY combo we got going on. But the same principle question applies: which model should be returning the result? --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Based on what you''ve shared, I''d put the finder on Company, since you want a set of companies. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
If you''ve got: class User < ActiveRecord::Base has_and_belongs_to_many :companies end class Company < ActiveRecord::Base has_and_belongs_to_many :users end All you need to do is: user = User.find(params[:id]) user.companies You don''t need to write a special finder: it''s built for you when you declare the model relationships. KumaZatheef wrote:> Ok, although not entirely new to RoR, myself and a colleague have been > "discussing" some best practices for `find`. > > The scenario: > - table of users > - table of companies > - a user can belong to multiple companies > - end result is that the list will be used for a select list. > > So, if I want to get a list of companies that a particular user has > been with in the last X time frame, which model should have the > specialized `find` (because we may / may not have to do a "GROUP BY" > as well). > > Should it be in the users model, because it''s all the companies would > have the user in common? > > Or: > > Should it be in the companies model, because it will be a collection > of companies? > > > Thanks in adavance-- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
@Brent: If the join was that straight forward then there wouldn''t be such an issue, but as I mentioned in my immediately follow up to the original post, the join is actually quite complex ... the optimized SQL is as such: (as displayed with checks in the function) query = "SELECT c.id as company_id, c.name as company_name FROM entries as e INNER JOIN project_tasks AS pt ON pt.id e.project_task_id INNER JOIN projects as p ON p.id = pt.project_id INNER JOIN jobs as j on j.id = p.job_id INNER JOIN companies as c ON c.id = j.company_id WHERE e.user_id = "+self.id.to_s+" " query += " AND entries.start_timestamp >= "+start_timestamp.to_s +" " if( !start_timestamp.nil? ) query += " AND entries.end_timestamp <= "+end_timestamp.to_s+" " if( !end_timestamp.nil? ) query += " AND c.active = "+is_active.to_s+" GROUP BY c.id ORDER BY max( e.start_timestamp ) DESC" Obviously this more complex than what I originally started polling about, but this gives insight into the end desired result. So the poll question remains: should this be in the User model (since it''s a user''s list of Companies), or be in the Company model since that''s what it''s actually returning. On Jan 25, 10:40 am, Brent Miller <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> If you''ve got: > > class User < ActiveRecord::Base > has_and_belongs_to_many :companies > end > > class Company < ActiveRecord::Base > has_and_belongs_to_many :users > end > > All you need to do is: > > user = User.find(params[:id]) > user.companies > > You don''t need to write a special finder: it''s built for you when you > declare the model relationships. > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
KumaZatheef wrote:> So the poll question remains: should this be in the User model (since > it''s a user''s list of Companies), or be in the Company model since > that''s what it''s actually returning. >In this case, I think it would belong in both places. I would make a pair of methods, that work together. One in User that asks Company for a list for itself, and then the method in Company that takes in the User''s id and returns the list. You wouldn''t want to put the method just in Users, because it''s stepping on Company''s toes by pulling data from Company''s table. On the other hand, you still want to be able to call user.companies. class Company < ActiveRecord::Base def self.find_for_user(id) # excecute the correct SQL, wrapping the results up the ActiveRecord way end end class User < ActiveRecord::Base def companies Company.find_for_user(self.id) end end -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Hmmm ... that''s a good way to cover possible scenarios. So the "real" call would be in Company, but Users would access it .... is that ok (ex: "standard") to have one Model accessing another''s functions ... for some reason I figured that''d be crossing into each other''s territory ... On Jan 25, 2:13 pm, Brent Miller <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> KumaZatheef wrote: > > So the poll question remains: should this be in the User model (since > > it''s a user''s list of Companies), or be in the Company model since > > that''s what it''s actually returning. > > In this case, I think it would belong in both places. I would make a > pair of methods, that work together. One in User that asks Company for > a list for itself, and then the method in Company that takes in the > User''s id and returns the list. > > You wouldn''t want to put the method just in Users, because it''s stepping > on Company''s toes by pulling data from Company''s table. On the other > hand, you still want to be able to call user.companies. > > class Company < ActiveRecord::Base > def self.find_for_user(id) > # excecute the correct SQL, wrapping the results up the ActiveRecord > way > end > end > > class User < ActiveRecord::Base > def companies > Company.find_for_user(self.id) > end > end > -- > Posted viahttp://www.ruby-forum.com/.--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
KumaZatheef wrote:> is that ok (ex: "standard") to have one Model accessing another''s > functions ... for some reason I figured that''d be crossing into each > other''s territory ...It is standard to have the models talk to each other. That''s what "has_and_belongs_to_many" and those sorts of relationship declarations do; they''re just meta-programming tools to create methods like the ones I''m suggesting. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
oh yeah, right .... duh. That makes sense, thanks a bunch for your feedback, much appreciated!! I''m curious what others have to say as well ... agree / disagree? On Jan 25, 4:30 pm, Brent Miller <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> KumaZatheef wrote: > > is that ok (ex: "standard") to have one Model accessing another''s > > functions ... for some reason I figured that''d be crossing into each > > other''s territory ... > > It is standard to have the models talk to each other. That''s what > "has_and_belongs_to_many" and those sorts of relationship declarations > do; they''re just meta-programming tools to create methods like the ones > I''m suggesting. > -- > Posted viahttp://www.ruby-forum.com/.--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
KumaZatheef wrote:> oh yeah, right .... duh. > That makes sense, thanks a bunch for your feedback, much appreciated!! > > I''m curious what others have to say as well ... agree / disagree? > > On Jan 25, 4:30 pm, Brent Miller <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org>Disagree: I would put that nasty looking query in the association itself. Sence that is something that is probably going to be a maintenance issue all by itsself, Id make it a module -- esp. because I bet you have more then one of these functions: ### #UserCompanyModule.rb Module UserCompanyAssociationMethods def been_at_sense(time) #or whatever #code here to get the right companies end #more methods here end ### class User has_and_belongs_to_many :companies, :extend=>UserCompanyAssociationMethods end #somewhere in your code user = User.find(...) companies = user.companies.been_at_sense(Time.now-2.years) ### As an aside, I think that habtm relationships are only useful in very simple circumstances. If the relationship is that complex you should use has_many and put some of the logic in joining tables eg: User: has_many :employments Company: has_many :employments Employment: belongs_to :user; belongs_to :company In any case, put these functions into models and use them to extend the associations themselves. Easier to test, Easier to maintain. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Hmmm ... interesting idea of putting it in a Module, never thought of that. I''ll take a look at the feasibility of doing it that way, within the context of our existing code. You''re right, we do have more than one of these functions; however, the others apply to associations between User and other Models (ex: jobs of a given company). Any other thoughts / ideas out there? I''m liking all of these suggestions so far .... thank you so much to those that have contributed, very helpful, much appreciated! On Jan 25, 6:54 pm, Starr Trader <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> KumaZatheef wrote: > > oh yeah, right .... duh. > > That makes sense, thanks a bunch for your feedback, much appreciated!! > > > I''m curious what others have to say as well ... agree / disagree? > > > On Jan 25, 4:30 pm, Brent Miller <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> > > Disagree: > > I would put that nasty looking query in the association itself. Sence > that is something that is probably going to be a maintenance issue all > by itsself, Id make it a module -- esp. because I bet you have more then > one of these functions: > > ### > #UserCompanyModule.rb > > Module UserCompanyAssociationMethods > def been_at_sense(time) #or whatever > #code here to get the right companies > end > > #more methods here > > end > > ### > class User > has_and_belongs_to_many :companies, > :extend=>UserCompanyAssociationMethods > end > > #somewhere in your code > > user = User.find(...) > companies = user.companies.been_at_sense(Time.now-2.years) > ### > > As an aside, I think that habtm relationships are only useful in very > simple circumstances. If the relationship is that complex you should > use has_many and put some of the logic in joining tables eg: > > User: has_many :employments > Company: has_many :employments > Employment: belongs_to :user; belongs_to :company > > In any case, put these functions into models and use them to extend the > associations themselves. Easier to test, Easier to maintain. > -- > Posted viahttp://www.ruby-forum.com/.--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---