开发者

duplicate rows in join table with has_many => through and accepts_nested_attributes_for

An event has many artists, and an artist has many events. The join model for an artist and an event is a performance. I want to add artists to an event.

This works except that I'm getting duplicate entries into my join table when creating a new event. This causes problems elsewhere.

event.rb

validates_presence_of :name, :location

has_many :performances, :dependent => :destroy
has_many :artists, :through => :performances

accepts_nested_attributes_for :artists, :reject_if => proc {|a| a['name'].blank?}
# accepts_nested_attributes_for :performances, :reject_if => proc { |a| a['artist_id'].blank? }

artist.rb

has_many :performances
has_many :events, :through => :performances

has_attached_file :photo, :styles => { :small =开发者_开发知识库> "150x150>"  },
              :url  => "/images/artists/:id/:style/:basename.:extension",
              :path => ":rails_root/public/images/artists/:id/:style/:basename.:extension"

# validates_attachment_presence :photo
validates_attachment_size :photo, :less_than => 5.megabytes
validates_attachment_content_type :photo, :content_type => ['image/jpeg', 'image/png']

validates_presence_of :name

has_many :mixes  

performance.rb

belongs_to :artist
belongs_to :event

events_controller.rb

def new
  @event = Event.new
  @event.artists.build

  respond_to do |format|
    format.html # new.html.erb
    format.xml  { render :xml => @event }
  end
end

def create
  @event = Event.new(params[:event])

  respond_to do |format|
    if @event.save
      flash[:notice] = 'Event was successfully created.'
      format.html { redirect_to(admin_events_url) }
      format.xml  { render :xml => @event, :status => :created, :location => @event }
    else
      format.html { render :action => "new" }
      format.xml  { render :xml => @event.errors, :status => :unprocessable_entity }
    end
  end
end

_form.html.erb

<% form_for([:admin,@event]) do |f| %>
<p>
    <%= f.label :name %><br />
    <%= f.text_field :name %>
</p>
<p>
    <%= f.label :location %><br/>
    <%= f.text_field :location %>
</p>
<p>
    <%= f.label :date %><br />
    <%= f.date_select :date %>
</p>
<p>
    <%= f.label :description %><br />
    <%= f.text_area :description %>
</p>
<% f.fields_for :artists do |builder| %>
    <p>   
        <%= builder.label :name, "Artist"%><br/>
        <%= builder.text_field :name %><br/>
    </p>
<% end %>
<p>
    <%= f.submit 'Submit' %> <%= link_to 'Cancel', admin_events_path %>
</p>
<% end %>

output with second accepts_nested_attributes_for commented out

Processing Admin::EventsController#create (for 127.0.0.1 at 2010-06-15 21:10:24) [POST]
Parameters: {"commit"=>"Submit", "authenticity_token"=>"KigiyUNIE2iYTwo59lf7SClbG9Dxge7WEWDDd08OLEc=", "event"=>{"name"=>"test event", "artists_attributes"=>{"0"=>{"name"=>"test artist"}}, "date(1i)"=>"2010", "location"=>"some location", "date(2i)"=>"6", "date(3i)"=>"16", "description"=>"blah"}}
User Columns (2.4ms)   SHOW FIELDS FROM `users`
User Load (0.3ms)   SELECT * FROM `users` WHERE (`users`.`id` = 13) LIMIT 1
Event Columns (1.2ms)   SHOW FIELDS FROM `events`
Artist Columns (1.4ms)   SHOW FIELDS FROM `artists`
SQL (0.1ms)   BEGIN
Event Create (0.3ms)   INSERT INTO `events` (`name`, `created_at`, `location`, `updated_at`, `date`, `description`) VALUES('test event', '2010-06-16 04:10:24', 'some location', '2010-06-16 04:10:24', '2010-06-16', 'blah')
Artist Create (0.2ms)   INSERT INTO `artists` (`name`, `created_at`, `photo_file_size`, `updated_at`, `photo_file_name`, `photo_content_type`, `photo_updated_at`, `bio`) VALUES('test artist', '2010-06-16 04:10:24', NULL, '2010-06-16 04:10:24', NULL, NULL, NULL, NULL)
[paperclip] Saving attachments.
Performance Columns (1.1ms)   SHOW FIELDS FROM `performances`
Performance Create (0.2ms)   INSERT INTO `performances` (`event_id`, `artist_id`) VALUES(10, 22)
Performance Create (0.1ms)   INSERT INTO `performances` (`event_id`, `artist_id`) VALUES(10, 22)
SQL (0.4ms)   COMMIT
Redirected to http://localhost:3000/admin/events
Completed in 97ms (DB: 8) | 302 Found [http://localhost/admin/events]


I just created a quick test rails app with the code you supplied and here are the results:

Processing EventsController#create (for 192.168.1.2 at 2010-06-16 00:33:05) [POST]
    Parameters: {"commit"=>"Create", "authenticity_token"=>"R8lKqeTIbRQ5Ft8K+TNMNusCh4qmnOv8xxSIi25MMNE=", "event"=>{"name"=>"Event", "artists_attributes"=>{"0"=>{"name"=>"Me"}}, "date(1i)"=>"2010", "location"=>"nowhere", "date(2i)"=>"6", "date(3i)"=>"16", "description"=>"Test Event"}}
      Event Create (0.4ms)   INSERT INTO "events" ("name", "location", "created_at", "updated_at", "date", "description") VALUES('Event', 'nowhere', '2010-06-16 04:33:05', '2010-06-16 04:33:05', '2010-06-16', 'Test Event')
      Artist Create (12.3ms)   INSERT INTO "artists" ("name", "created_at", "updated_at") VALUES('Me', '2010-06-16 04:33:05', '2010-06-16 04:33:05')
      Performance Create (0.2ms)   INSERT INTO "performances" ("name", "created_at", "event_id", "updated_at", "artist_id") VALUES(NULL, '2010-06-16 04:33:05', 1, '2010-06-16 04:33:05', 1)
    Redirected to http://192.168.1.5:3000/events/1
    Completed in 251ms (DB: 13) | 302 Found [http://192.168.1.5/events]

What version of Rails are you running?

Have you tried creating a clean test app to see if it works?

There may be a gem or some plugin that's causing an issue. I'm running 2.3.8 with SQLite3.

I do not get all of the extra output you are showing, which may be something MySQL specific related to the has_many :through relationship, but that's something to look at as well.

Here is my schema for reference:

  create_table "artists", :force => true do |t|
    t.string   "name"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "events", :force => true do |t|
    t.string   "name"
    t.string   "location"
    t.date     "date"
    t.text     "description"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "performances", :force => true do |t|
    t.string   "name"
    t.integer  "artist_id"
    t.integer  "event_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end


This was solved by updating Rails to the latest version, 2.3.8. This appears to be a bug in 2.3.5.

https://rails.lighthouseapp.com/projects/8994/tickets/3659-accepts_nested_attributes_for-causes-duplicate-entries-in-join-model-table

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜