Artists have many Events. Events have many Artists. The join between these two models is called Performances.
Currently the Event form creates the Performance but creates a new artist for each Artist added to the Event form.
I would like the Event form to:
- Validate that an Artist can only be added to an Event once
- If an Artist with the same name already exists in the Artists table, create the association in the join table (Performances), but do not create another Artist
- If an Artist with the same name does not already exist, create it and the Performance
I've tried adding 'validates_uniqueness_of :name' to artist.rb but this prevents the event from being saved. The join (performance) should be created if it does not already exist and the artist should be created if it does not already exist, but the existence of the artist should not prevent the join/association from being created.
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?}, :allow_destroy => true
artist.rb
has_many :performances
has_many :events, :through => :performances
perfomance.rb
belongs_to :artist
belongs_to :event
events_controller.rb
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| %>
<%= render 'artist_fields', :f => builder %>
<% end %>
<p><%= link_to_add_fields "Add Artist", f, :artists %></p>
<p>
<%= f.submit 'Submit' %> <%= link_to 'Cancel', admin_events_path %>
</p>
<% end %>
artist_fields.html.erb
<p class="fields">
<%= f.label :name, "Artist"%><br/>
<%= f.text_field :name %>
<%= link_to_remove_fields "remove", f %>
</p>