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.