Reputation: 1094
I have an author, who writes products, which are placed in groups. What I want to do is to list the groups that an author is involved into.
So, I have first to follow the link from author to products, which works with :
@author = Author.find(params[:id])
@products = @author.products
which gives lot of products :-) Then I have to find (all) the groups that are linked to all of the products (because a group can contain a lot of products, I have already a has_many link with group_id column in the product table)
But when I try to write something as
@groups = @author.products.groups
I get the error : undefined method `groups' for # Class:0x000000032a2198
Why ?
Here is the model, where only the "through" clauses seem not to work ?
class Author < ActiveRecord::Base
has_and_belongs_to_many :products
has_many :groups, :through => :products
end
class Product < ActiveRecord::Base
belongs_to :group
has_and_belongs_to_many :authors
end
class Group < ActiveRecord::Base
has_many :products, :dependent => :destroy
has_many :authors, :through => :products
end
Thanks !
Edit : I found an ugly way to do what I want. But is there no better RoR way ??
def show
@author = Author.find(params[:id])
@products = @author.products
@groups = []
@products.each do |product|
group = Group.find(product.group_id)
unless @groups.include?(group)
@groups << group
end
end
end
Upvotes: 1
Views: 88
Reputation: 1283
As far as I know there's no way to do it in a Rails way. First, here's how to make what you have more "Railsy":
def show
@author = Author.find(params[:id])
@products = @author.products
@groups = []
@products.each do |product|
unless @groups.include?(product.group)
@groups << group
end
end
end
But a shorter way would be:
@products.map(&:group).uniq
Quick explanation of what it's doing. First it's using the symbol to proc shorthand that was introduced in Rails 1.1 (http://blog.hasmanythrough.com/2006/3/7/symbol-to-proc-shorthand). That builds an array of groups. Then b/c, in your question, you are checking for uniqueness (using include?) I call .uniq which weeds out any duplicates.
Upvotes: 1
Reputation: 1094
I also found another way to do this :
@user = User.find(params[:id])
@groupcollect = []
@user.products.each { |e| @groupcollect << e.group_id} # collect group_id for all products
@mygroups = Group.find(@groupcollect.uniq) # gets the groups for all group_id, unique
:-)
Upvotes: 0