【问题标题】:ruby on rails force a has_many relationship, at least oneruby on rails 强制一个 has_many 关系,至少一个
【发布时间】:2014-04-23 16:23:48
【问题描述】:

下面是我的评论控制器的创建功能。基本上我遇到的问题是,如果一个场地是空白的,而艺术家不是,那么仍然会创建一个艺术家对象而不会创建一个音乐会对象。演唱会创建失败,如何防止创建艺人?如果这不可行,如何在演唱会创建失败后立即删除艺人?

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

音乐会属于艺术家

音乐会有_很多评论

我需要强制一位艺人至少举办一场音乐会。

【问题讨论】:

  • ActiveRecord::Base.transaction 如果 db 配备事务,则运行良好。
  • 你能详细说明@KNaito

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


【解决方案1】:

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

transaction do
  <ActiveRecord operations>
end

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

【讨论】:

  • 这是在我的控制器中,如果我尝试这样做,我会收到评论控制器的错误未定义方法“事务”
  • 这是因为模型中使用了事务。因此,您应该将代码移动到模型中以使其工作。无论如何,你的方法也很好,虽然它可以使用一些重构。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-12
      • 2011-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多