艺术家有很多活动。活动有很多艺术家。这两个模型之间的连接称为Performances。
目前,“事件”表单会创建“演奏组”,但会为添加到“事件”表单的每个艺术家创建一个新的艺术家。
我希望活动表格能够:
我尝试将'validates_uniqueness_of:name'添加到artist.rb,但这可以防止事件被保存。如果连接(性能)尚不存在,则应创建连接(性能),如果艺术家尚不存在,则应创建艺术家,但艺术家的存在不应阻止创建连接/关联。
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>
答案 0 :(得分:1)
如果名称为空白,您可以使用proc来拒绝艺术家属性:如果艺术家已经存在于模型中,您也可以拒绝它,但这并不能解决重复艺术家的问题。基本上,您希望在将事件添加到事件时执行find_or_create_by_name。
我认为在您的情况下,最好定义自己的artist_attributes=
方法,而不是依赖accepts_nested。这样,您可以查找每个艺术家名称,并仅根据需要添加它:
def artist_attributes=(params)
if existing_artist = Artist.find_by_name(params[:name])
self.artists << existing_artist unless self.artists.include? existing_artist
else
self.build_artist(params)
end
end
答案 1 :(得分:1)
你应该看看这些Railscasts:
不要创作各种艺术家。只需使用现有的(或创建,如果需要):
http://railscasts.com/episodes/167-more-on-virtual-attributes
您还可以检查这些嵌套表单railscast(此处链接的第一部分):
对于验证,您可以让方法为您进行一次性事件验证。像(在Event.rb上)的东西:
validate :artists_appear_just_once
private
def artists_appear_just_once
self.artists.size == self.artists.uniq.size
end
或者,您可以使用uniq默认显示artsits一次!保存前的方法。只需调用before_save挂钩并处理艺术家数组......
before_save :make_artists_unique
private
def make_artists_unique
artists.uniq!
end
希望我得到你需要的东西:P