下面是我为reviews控制器创建的函数。基本上,我遇到的问题是,如果一个场地是空白的,而艺术家不是,那么艺术家对象仍然会被创建,而音乐会对象则不会。如果音乐会无法创作,我该如何阻止艺术家被创作?如果这不可能,我如何在演唱会创作失败后立即删除艺术家?
def create
date_string = "#{review_params['date(1i)']}-#{review_params['date(2i)']}-#{review_params['date(3i)']}"
artist_string = review_params[:artist].titleize
venue_string = review_params[:venue].titleize
@concert = Concert.find_or_create_by!(artist: Artist.find_or_create_by!(name: artist_string), venue: venue_string, date: date_string)
@review = @concert.reviews.create(review_params)
@review.user_id = session[:user_id]
end
艺术家has_many:音乐会
属于艺术家的音乐会
音乐会有许多评论
我需要强迫一个艺术家至少开一场音乐会。
我认为KNaito意味着您可以包装代码,以便在事务中创建记录。如果事务中的任何ActiveRecord操作失败,则所有更改都将回滚。示例:
transaction do
<ActiveRecord operations>
end
附言:这应该在模型内的方法中完成。您可以通过控制器操作调用此方法。
所以我最终这样做是为了解决这个问题。如果有人有更干净或更聪明的方法,请告诉我。
def create
date_string = "#{review_params['date(1i)']}-#{review_params['date(2i)']}-#{review_params['date(3i)']}"
artist_string = review_params[:artist].titleize
venue_string = review_params[:venue].titleize
@review = Review.create(review_params)
if @review.save
@artist = Artist.find_or_create_by(name: artist_string)
@concert = Concert.find_or_create_by(artist: @artist, venue: venue_string, date: date_string)
@review.concert_id = @concert.id
@review.user_id = session[:user_id]
@review.save
end
我的答案与rails4guides.com的答案相同。代码如下。
def create
date_string = "#{review_params['date(1i)']}-#{review_params['date(2i)']}-#{review_params['date(3i)']}"
artist_string = review_params[:artist].titleize
venue_string = review_params[:venue].titleize
ActiveRecord::Base.transaction do
@concert = Concert.find_or_create_by!(artist: Artist.find_or_create_by!(name: artist_string), venue: venue_string, date: date_string)
raise "no concert" unless @concert
@review = @concert.reviews.create(review_params)
@review.user_id = session[:user_id]
end
rescue => e
# rollback
end