ruby on rails强制has_many关系,至少一个

时间:2014-04-23 05:20:59

标签: ruby-on-rails-4 has-many controllers database-relations

以下是我的评论控制器的创建功能。基本上我遇到的问题是,如果一个场地留空,而艺术家不是,则仍然会创建一个艺术家对象,而不是一个音乐会对象。如果音乐会无法创建,如何防止创建艺术家?如果无法做到这一点,如何在音乐会无法创建后立即删除艺术家?

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:音乐会

音乐会belongs_to artist

音乐会has_many评论

我需要强迫艺术家至少举办一场音乐会。

3 个答案:

答案 0 :(得分:2)

我认为KNaito意味着您可以包装代码以在事务中创建记录。如果事务中的任何ActiveRecord操作失败,则将回滚所有更改。例如:

transaction do
  <ActiveRecord operations>
end

P.S。这应该在模型中的方法中完成。您可以从控制器操作中调用此方法。

答案 1 :(得分:0)

所以我最终这样做是为了解决这个问题。如果有人有更清洁或更聪明的方式,请告诉我。

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

答案 2 :(得分:0)

我的回答与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