Hello and happy new year :) My application has users, memberships, projects, and entries. Briefly, a project has many entries and users are granted access to such entries based on a project membership (a full-blown model, not a simple join table). class User < ActiveRecord::Base has_many :memberships has_many :projects, :through => :memberships ... class Membership < ActiveRecord::Base belongs_to :user belongs_to :project ... class Project < ActiveRecord::Base has_many :memberships has_many :users, :through => :memberships has_and_belongs_to_many :entries ... class Entry < ActiveRecord::Base has_and_belongs_to_many :projects belongs_to :content, :polymorphic => true ... Now I would like, for example, to get the title of all entries to which the current user has access to, from all projects she may be part of. Although each entry can belong to any number of projects, and users can be members of any number of projects, each entry should be retrieved only once. I believe that this can be done in SQL with something like (assuming that the current user''s id is 1): SELECT DISTINCT title FROM entries INNER JOIN entries_projects ON entries.id=entries_projects.entry_id WHERE project_id IN (SELECT project_id FROM memberships WHERE user_id=1); But my question is whether the same can be accomplished in idiomatic rails style through the AR facilities, something along the lines of @current_user.projects.entries (which obviously won''t work) Thanks in advance for any advice. Cheers, Giuseppe -- 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 -~----------~----~----~----~------~----~------~--~---
Hi again... still hoping that someone might have some insight. As a newbie, I would also appreciate any feedback regarding the post itself, as in "it''s too vague, too obscure, too specific, out-of-place, etc." I''ll gladly take any well-deserved hammering! :-) Ciao, Giuseppe -- 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 -~----------~----~----~----~------~----~------~--~---
Hi Guiseppe, I found your post well written. I think posts that are more difficult to respond to tend to languish. I couldn''t think of a good Rails way to do this other than the following. You could add your own find_titles method to Entry like this: class Entry < ActiveRecord::Base has_and_belongs_to_many :projects belongs_to :content, :polymorphic => true def self.find_titles(user_id) entries = find(:all, :select => "distinct(title)", :joins => "inner join entries_projects ON entries.id=entries_projects.entry_id", :conditions => [" project_id IN(SELECT project_id FROM memberships WHERE user_id= ?)", user_id]) entries.map {|e| e.title} end end And then you could call it like this: Entry.find_titles(1) It makes your code cleaner. Better yet, you could put this code in a new instance method in User called "titles" and then just call @user.titles although in the titles method you would want to say Entry.find_titles(self.id). -Paul --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Hi Paul, many thanks for the feedback. I am still trying to get a feel for the language and the framework. In this case, the way ''find'' is used looks a lot like sql broken down in several pieces, so I wonder what is the advantage over using straight find_by_sql. Meanwhile, preliminary testing shows that the following might just work, although some more testing is needed. @entries = @current_user.projects.map{|g| g.entries}.flatten.uniq The flattening trick was inspired by: http://www.rubyonrailsblog.com/articles/2006/10/04/ruby-on-rails-cheat-sheet-collectors-edition Putting together this rather obscure line of code was fun, even though I still need to develop a *pragmatic* sense of whether it was the right kind of effort in the first place. Buona notte, Giuseppe -- 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 -~----------~----~----~----~------~----~------~--~---
On 1/5/07, Giuseppe Bertini <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > Hi Paul, > many thanks for the feedback. > I am still trying to get a feel for the language and the framework. > In this case, the way ''find'' is used looks a lot like sql broken down in > several pieces, so I wonder what is the advantage over using straight > find_by_sql.I agree. IMO you gain nothing, but make the query a fair bit harder to read. I don''t think AR is meant to supplant SQL, the rails devs would be crazy to believe they could, it''s more about making the simple stuff more convenient.> Meanwhile, preliminary testing shows that the following might just work, > although some more testing is needed. > > @entries = @current_user.projects.map{|g| g.entries}.flatten.uniqHmm.. If you can manage to get the entries loaded eagerly, and there aren''t too many duplicates, something like this approach may work ok.. Using AR may be more portable in some cases, but if db independence is a _real_ requirement, and you''re working on a serious app, you''ll need some way to look up db-specific sql anyway (and this particular query looks fairly standard). Just my $0.02, Isak> > The flattening trick was inspired by: > http://www.rubyonrailsblog.com/articles/2006/10/04/ruby-on-rails-cheat-sheet-collectors-edition > > Putting together this rather obscure line of code was fun, even though I > still need to develop a *pragmatic* sense of whether it was the right > kind of effort in the first place. > > Buona notte, > Giuseppe > > -- > 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 -~----------~----~----~----~------~----~------~--~---
On 1/4/07, Giuseppe Bertini <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> I am still trying to get a feel for the language and the framework. > In this case, the way ''find'' is used looks a lot like sql broken down in > several pieces, so I wonder what is the advantage over using straight > find_by_sql.One advantage would be that if you use ActiveRecord''s with_scope method (which facilitates many cool DB tricks), and your find is made within its block, the scope will automatically be applied to it. I don''t think that this happens with find_by_sql, looking at the with_scope code. There might be other benefits.> Meanwhile, preliminary testing shows that the following might just work, > although some more testing is needed. > > @entries = @current_user.projects.map{|g| g.entries}.flatten.uniq > > The flattening trick was inspired by: > http://www.rubyonrailsblog.com/articles/2006/10/04/ruby-on-rails-cheat-sheet-collectors-edition > > Putting together this rather obscure line of code was fun, even though I > still need to develop a *pragmatic* sense of whether it was the right > kind of effort in the first place.If you know @current_user.projects won''t return "a lot" of results, then this is fine. If this line slows down your page though, you''ll know it''s because you''re making Ruby do too much of the database server''s work and moving back to the SQL solution will probably help.> Buona notte, > GiuseppeSincerely, Tom Lieber http://AllTom.com/ http://GadgetLife.org/ --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---