Strugling with has_many :through

HABTM does have its use. If your domain does not need any attributes other than the foreign keys of the tables that are connected then HABTM is good enough. In this case the association class is just a join table.

When your application demands that other attributes needs to be persisted that belongs to the association class then you have to go for the has_many :through relationship.

I have the following tables/objects…

class Currency < ActiveRecord::Base has_many :product_prices

has_many :products, :through => :product_prices end

class Product < ActiveRecord::Base has_many :product_prices has_many :currencies, :through => :product_prices end

class ProductPrice < ActiveRecord::Base

belongs_to :product belongs_to :currency end

Is that the correct configuration for what is effectivly a HABTM relationship? If not could somone please point me in the right direction!!

This is correct.

Furthermore, if i wanted to submit data into the product prices table/object, how would i do that? The same was as any other commit?

Object.new(params[:object]) ?

When a product is associated to the currency, you can do:

product_price = ProductPrice.new

product_price.attribute1 = params[:attribute1]

and so on.

But when i submit, it sets both values to the same value. I know i need somthing like… params[:prices][1][:unit_price] and so on, with array

indexes, but how do achive this in the HTML form with the rails helpers? Ive tried all sorts!!

What version of Rails are you using?

Instead of using:

@prices = @product.product_prices.new(params[:prices])

Try this:

@prices = ProductPrice.new(params[:prices])

@product.product_prices << @prices

price, i would want to have the form effectivly generate somthing like

So you have both Euro and Sterling price displayed on the page as text fields? And you want to populate those into your product_prices table?

@prices = ProductPrice.new(params[:euro_price]) @product.product_prices << @prices

@prices = ProductPrice.new(params[:sterling_price]) @product.product_prices << @prices

Will this solution work for your scenario?

How does your screen look like? I really don’t understand what you are saying. Can you explain clearly without making any assumption what you are trying to do?

class Currency < ActiveRecord::Base has_many :product_prices has_many :products, :through => :product_prices

end

class Product < ActiveRecord::Base has_many :product_prices has_many :currencies, :through => :product_prices end

class ProductPrices < ActiveRecord::Base belongs_to :products

belongs_to :currencies end

So thus, im building an administration where when the client wants to add a new product, they fill in the details, and say that the currencies table has two rows, one for euro, and one for sterling, the add product

screen would present two text feilds needing both an inputed price for sterling for that product and one for euro.

So you see, when i pass the post back to my controller, how do i handle having two (or more, based on wats in the currencies table) rows to

insert into the product_prices table?

Your question basically boils down to “How to create a new :through association?”. You can create :through association using the << method. Both Product and Price must be saved before you can use that operator.

So,

product = Product.create(:name => “DVD”)

euro_price = Currency.create(:amount => 123)

dollar_price = Currency.create(:amount => 99)

product.currencies << euro_price

product.currencies << dollar_price

You can define two fields name euro_price and dollar_price in your view. When the user submits, you can do the above in your action.