문제

The question is: given two models A and B being in HABTM association, when I create new instance of A, how to instruct Rails not to write to A, B and A_B, but just to A and A_B?

So, more precisely: I have two associated models: Balloon and Color

class Balloon < ActiveRecord::Base
  has_and_belongs_to_many :colors
end 
class Color < ActiveRecord::Base
  has_and_belongs_to_many :balloons
end

_form.html.haml contains:

  .field
    = f.label :color
    - Color.all.each{|c|
    = check_box_tag("color[]", c.name)
    = c.name
    -}

and the Balloon controller:

  def create
    @balloon = Balloon.new(params[:balloon])
    params[:color].each do |col|
      @balloon.colors.build(:name=>col)
    end
    ....

When I save, I have the following records in the tables:

sqlite> select * from balloons;
1|b1
2|b2
3|b3
4|b4

sqlite> select * from colors;
1|red
2|green
3|red
4|red
5|red


sqlite> select * from balloons_colors;
1|1
1|2
2|3
3|4
4|5

The problem is that I don't want that table Colors receive duplicated records, I want that the table responsible for association (balloons_colors) gets additional records everytime I add a balloon. So I want to have something like

sqlite> select * from colors;
1|red
2|green

sqlite> select * from balloons_colors;
1|1
1|2
2|1
3|1
4|1

Edited: schema is added:

sqlite> .schema balloons_colors 
CREATE TABLE "balloons_colors" ("balloon_id" integer, "color_id" integer); 

This table was created by the following migration

class BalloonsHaveAndBelongToManyColors < ActiveRecord::Migration
  def self.up
    create_table :balloons_colors, :id => false do |t|
      t.references :balloon, :color
    end
  end
.....
end
도움이 되었습니까?

해결책

the problem is that you use build on @ballon.colors. Build instantiates a new color instead of finding one. Adding a member to the collection is usually done this way :

@color = Color.find(params[:color_id]) 
@balloon.colors << @color

another way is to use nested attributes.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top