Thanks again Marco,

I ended up adding a references to my previous query, and it seems its 
working fine now:

@compositions = @product.compositions.includes(:material).references(:
materials)

Regards,
Leandro

On Monday, March 30, 2015 at 12:26:43 PM UTC-3, Marco Antonio wrote:
>
> Hi Leandro,
>
> You can reach the materials through the compositions, and you should worry 
> about doing extra queries in the DB since you have used the includes 
> method. You should iterate through them to get the list of material names.
>
> Say we have:
>
> @compositions = @p.compositions.include(:materials)
> @material_names = @compositions.map { |c| c.materials.map(&:name) }
>
> @material_names will return you an array of arrays with the material names.
>
> Since you have the has many through setup, you can call 
> @product.materials.map(&:name) directly and you will get a flattened array 
> with the materials' names.
>
> Best regards,
> Marco
>
> On Mon, Mar 30, 2015 at 4:33 PM, Leandro França <[email protected] 
> <javascript:>> wrote:
>
>>
>> Hey Marco,
>>
>> Thanks a lot for you quick response.
>>
>> So, I tried to change my models to use only *has_many* and *belongs_to*, 
>> instead of *has_and_belongs_to_many*.
>> I also added the foreign key to material_id:
>>
>>
>>
>> class Composition < ActiveRecord::Base
>>   belongs_to :material, :class_name => "Material", :foreign_key => 
>> 'material_id'
>>   belongs_to :product
>> end
>>
>>
>> class Material < ActiveRecord::Base
>>  has_many :compositions
>>  has_many :products, through: :composition
>> end
>>     
>> class Product < ActiveRecord::Base
>>   has_many :compositions
>>   has_many :materials, through: :composition
>> end
>>
>> On rails console, I can run fine:
>>
>> @p = Product.first
>> @p.compositions
>> @p.compositions.includes(:material)
>>
>> But this last one returns me only the items I already have on 
>> composition, not the actual material attributes.
>>
>>
>> @p.compositions.includes(:material)
>>   Composition Load (0.5ms)  SELECT "compositions".* FROM "compositions" 
>> WHERE "compositions"."product_id" = $1  [["product_id", 1]]
>>   Material Load (0.7ms)  SELECT "materials".* FROM "materials" WHERE 
>> "materials"."id" IN (1, 2)
>> => #<ActiveRecord::AssociationRelation [#<Composition id: 5, product_id: 
>> 1, material_id: 1, material_quantity: 3, created_at: "2015-03-30 05:20:27", 
>> updated_at: "2015-03-30 05:20:27">, #<Composition id: 6, product_id: 1, 
>> material_id: 2, material_quantity: 2, created_at: "2015-03-30 05:20:27", 
>> updated_at: "2015-03-30 05:20:27">]>
>>
>> I would like to also get the material names from Material model.
>> How do I get them using this approach?
>>
>> Thanks again,
>> Leandro
>>
>>
>> On Monday, March 30, 2015 at 10:58:52 AM UTC-3, Marco Antonio wrote:
>>>
>>> Now I see that you have the quantity inside your compositions table and 
>>> you probably need that.
>>>
>>> You can use the code you have in your controller normally with the 
>>> changes mentioned in my last e-mail.
>>>
>>> *Marco Almeida*
>>> about.me/marcoafilho
>>> +45 31 65 28 84
>>>
>>> On Mon, Mar 30, 2015 at 3:53 PM, Marco Antonio Almeida <
>>> [email protected]> wrote:
>>>
>>>> Hi Leandro,
>>>>
>>>> The way it is set up right now, you would actually have in the 
>>>> Composition model a belongs_to :material. And the Material would have a 
>>>> has_many :compositions.
>>>>
>>>> Verify that you have the foreign key set in your Composition model, so 
>>>> you would never be able to do something like: composition.materials.
>>>>
>>>> Since you have the has_many through association you could simply call. 
>>>> @product.materials and it will return what you want (It will do the INNER 
>>>> JOIN through the compositions table).
>>>>
>>>> The error you're getting is because when you're using a has_and_belongs 
>>>> to many, Rails expect to have a relationship table named after the two 
>>>> models in the plural. But in this case your compositions table is already 
>>>> the relationship table.
>>>>
>>>> Best regards,
>>>> Marco Almeida
>>>>
>>>> On Mon, Mar 30, 2015 at 3:20 PM, Leandro França <[email protected]
>>>> > wrote:
>>>>
>>>>> Hi there,
>>>>>
>>>>> I'm learning the active model, and I'm trying to retrieve an 
>>>>> association.
>>>>>
>>>>> My models are:
>>>>>
>>>>> class Composition < ActiveRecord::Base
>>>>>   has_and_belongs_to_many :materials
>>>>>   belongs_to :product
>>>>> end
>>>>>   
>>>>> class Material < ActiveRecord::Base
>>>>>  has_and_belongs_to_many :compositions
>>>>>  has_many :products, through: :composition
>>>>> end
>>>>>     
>>>>> class Product < ActiveRecord::Base
>>>>>   has_many :compositions
>>>>>   has_many :materials, through: :composition
>>>>>   accepts_nested_attributes_for :materials
>>>>> end
>>>>>
>>>>>
>>>>> My schema is:
>>>>>
>>>>>  
>>>>>  create_table "compositions", force: :cascade do |t|
>>>>>     t.integer  "product_id"
>>>>>     t.integer  "material_id"
>>>>>     t.integer  "material_quantity"
>>>>>     t.datetime "created_at",        null: false
>>>>>     t.datetime "updated_at",        null: false
>>>>>   end
>>>>>
>>>>>
>>>>>   create_table "materials", force: :cascade do |t|
>>>>>     t.string   "name"
>>>>>     t.decimal  "unit_cost"
>>>>>     t.string   "unit_measure"
>>>>>     t.datetime "created_at",   null: false
>>>>>     t.datetime "updated_at",   null: false
>>>>>   end
>>>>>
>>>>>
>>>>>   create_table "products", force: :cascade do |t|
>>>>>     t.string   "name"
>>>>>     t.string   "description"
>>>>>     t.datetime "created_at",  null: false
>>>>>     t.datetime "updated_at",  null: false
>>>>>   end
>>>>>
>>>>> On my CompositionsController index method, I would like to retrieve 
>>>>> all raw materials for a product id.
>>>>>
>>>>> What i have  now is:
>>>>>
>>>>>   def index
>>>>>     @product = Product.find(params[:product_id])
>>>>>     @compositions = @product.compositions
>>>>>   end
>>>>>
>>>>>
>>>>> How do I retrieve materials attributes from @compositions?
>>>>>
>>>>> When I try to use   
>>>>> @compositions = @product.compositions.includes(:materials)
>>>>> It gives me the error:
>>>>>
>>>>> PG::UndefinedTable: ERROR:  relation "compositions_materials" does not 
>>>>> exist
>>>>> LINE 5:                WHERE a.attrelid = '"compositions_materials"'...
>>>>>                                           ^
>>>>> :               SELECT a.attname, format_type(a.atttypid, a.atttypmod),
>>>>>                      pg_get_expr(d.adbin, d.adrelid), a.attnotnull, 
>>>>> a.atttypid, a.atttypmod
>>>>>                 FROM pg_attribute a LEFT JOIN pg_attrdef d
>>>>>                   ON a.attrelid = d.adrelid AND a.attnum = d.adnum
>>>>>                WHERE a.attrelid = '"compositions_materials"'::regclass
>>>>>                  AND a.attnum > 0 AND NOT a.attisdropped
>>>>>                ORDER BY a.attnum
>>>>>
>>>>>
>>>>>
>>>>> Any hints?
>>>>>
>>>>> Thanks in advance,
>>>>> Leandro
>>>>>
>>>>> -- 
>>>>> You received this message because you are subscribed to the Google 
>>>>> Groups "Ruby on Rails: Talk" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>>> an email to [email protected].
>>>>> To post to this group, send email to [email protected].
>>>>> To view this discussion on the web visit https://groups.google.com/d/
>>>>> msgid/rubyonrails-talk/643eb535-3085-46d4-b77b-
>>>>> 5c50c6cb7636%40googlegroups.com 
>>>>> <https://groups.google.com/d/msgid/rubyonrails-talk/643eb535-3085-46d4-b77b-5c50c6cb7636%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>> .
>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>
>>>>
>>>>
>>>  -- 
>> You received this message because you are subscribed to the Google Groups 
>> "Ruby on Rails: Talk" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to [email protected] <javascript:>.
>> To post to this group, send email to [email protected] 
>> <javascript:>.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/rubyonrails-talk/be51416c-4340-4c12-afff-702f67820f0f%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/rubyonrails-talk/be51416c-4340-4c12-afff-702f67820f0f%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/rubyonrails-talk/fe831975-beec-4c03-9de8-99e1b8cc96dc%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to