Hi all,
I have a intuitive category->subcategory->article relation. Categories 
have subcategories, subcategories belong to categories and have 
articles, articles belong to subcategories.
I am trying to write an action that will show a specific category with 
all its subcategories and objects in those subcategories.
def show
   @category = Category.find_by_name @params[''name'']
   @subcategories = Subcategory.find_all "category_id =
#{@category.id}"
   @articles = Article.find_all ???
end
Hw would I write the condition for coming up with all the articles in 
the selected subcategories (and thus the category to be displayed)?
I could do it the hard way, iterating over @subcategories and 
collecting all ids in a temp array, then selecting all articles whose 
subcategory_id is in the temp array. I suspect there is an easier way 
though. :-)
Many thanks in advance!
-- Nicky
Hello,
I would say that the most efficient way would be to add a instance
method on the Category class like that :
class Category
[...]
   def all_articles
       Article.find_by_sql ["select a.* from articles a,subcategories
s where a.subcategory_id=s.id and s.category_id=?",id]
   end
[...]
end
Then in your controller : 
def show
   @category = Category.find_by_name @params[''name'']
   @articles = @category.all_articles
end
Hope this helps
Michel
On Fri, 25 Feb 2005 15:21:42 +0100, Nickolay Kolev
<nmkolev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
wrote:> Hi all,
> 
> I have a intuitive category->subcategory->article relation.
Categories
> have subcategories, subcategories belong to categories and have
> articles, articles belong to subcategories.
> 
> I am trying to write an action that will show a specific category with
> all its subcategories and objects in those subcategories.
> 
> def show
>    @category = Category.find_by_name @params[''name'']
>    @subcategories = Subcategory.find_all "category_id =
#{@category.id}"
>    @articles = Article.find_all ???
> end
> 
> Hw would I write the condition for coming up with all the articles in
> the selected subcategories (and thus the category to be displayed)?
> 
> I could do it the hard way, iterating over @subcategories and
> collecting all ids in a temp array, then selecting all articles whose
> subcategory_id is in the temp array. I suspect there is an easier way
> though. :-)
> 
> Many thanks in advance!
> 
> -- Nicky
> 
> _______________________________________________
> Rails mailing list
> Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
> http://lists.rubyonrails.org/mailman/listinfo/rails
>
On Fri, 25 Feb 2005 15:21:42 +0100, Nickolay Kolev <nmkolev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Hi all, > > I have a intuitive category->subcategory->article relation. Categories > have subcategories, subcategories belong to categories and have > articles, articles belong to subcategories. > > I am trying to write an action that will show a specific category with > all its subcategories and objects in those subcategories. > > def show > @category = Category.find_by_name @params[''name''] > @subcategories = Subcategory.find_all "category_id = #{@category.id}" > @articles = Article.find_all ??? > end > > Hw would I write the condition for coming up with all the articles in > the selected subcategories (and thus the category to be displayed)? > > I could do it the hard way, iterating over @subcategories and > collecting all ids in a temp array, then selecting all articles whose > subcategory_id is in the temp array. I suspect there is an easier way > though. :-)First, your subcategories query should use parameters. It''s not exactly required in your specific case, but it''s a good habit to get into IMO: @subcategories = Subcategory.find_all [''category_id = ?'', @category.id] As for the Articles problem, try this: # replaces subcategories w/ ? and joins to a comma separated string sql = ''subcategory_id IN (%s)'' % @subcategories.fill(''?'').join('','') @articles = Article.find_all([sql] + @subcategories.collect { |sc| sc.id }) Basically, this should give you a query like ''subcategory_id IN (?, ?, ?)'' and give it parameters for each ID. -- rick http://techno-weenie.net
I ended up writing it like this:
class Article < ActiveRecord::Base
   belongs_to :subcategory
   def self.find_by_list_of_subcategories(subcategories)
     articles = Array.new
     subcategories.each {|sc| articles << sc.articles}
     return articles
   end
end
Is it fundamentally wrong or can I leave it like this? :-)
I much rather prefer working with a class method like this one and 
avoid constructing custom SQL queries.
-- Nicky
Michel''s method and my own execute one query, where yours executes 1 per sub category. On Fri, 25 Feb 2005 15:45:59 +0100, Nickolay Kolev <nmkolev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> I ended up writing it like this: > > class Article < ActiveRecord::Base > > belongs_to :subcategory > > def self.find_by_list_of_subcategories(subcategories) > articles = Array.new > subcategories.each {|sc| articles << sc.articles} > return articles > end > > end > > Is it fundamentally wrong or can I leave it like this? :-) > I much rather prefer working with a class method like this one and > avoid constructing custom SQL queries. > > -- Nicky > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- rick http://techno-weenie.net
On Fri, Feb 25, 2005 at 03:45:59PM +0100, Nickolay Kolev wrote:> I ended up writing it like this: > > class Article < ActiveRecord::Base > > belongs_to :subcategory > > def self.find_by_list_of_subcategories(subcategories) > articles = Array.new > subcategories.each {|sc| articles << sc.articles} > return articles > end > > end > > Is it fundamentally wrong or can I leave it like this? :-) > I much rather prefer working with a class method like this one and > avoid constructing custom SQL queries.This could be something like: def self.find_by_list_of_subcategories(subcategories) subcategories.inject([]) {|ar, sc| ar.concat sc.articles} end You might end up wrapping find_by_sql if performance proves to be an issue. marcel -- Marcel Molina Jr. <marcel-WRrfy3IlpWYdnm+yROfE0A@public.gmane.org>
> Michel''s method and my own execute one query, where yours executes 1 > per sub category.Point taken.>> class Article < ActiveRecord::Base >> >> belongs_to :subcategory >> >> def self.find_by_list_of_subcategories(subcategories) >> articles = Array.new >> subcategories.each {|sc| articles << sc.articles}This sould have been subcategories.each {|sc| articles += sc.articles} of course.>> return articles >> end >> >> end-- Nicky