Rails替换集合,而不是从has_many嵌套属性表单中添加它

时间:2014-11-27 00:40:20

标签: ruby-on-rails ruby-on-rails-4

我有这些模型(为便于阅读而简化):

class Place < ActiveRecord::Base
  has_many :business_hours, dependent: :destroy

  accepts_nested_attributes_for :business_hours
end

class BusinessHour < ActiveRecord::Base
  belongs_to :place
end

这个控制器:

class Admin::PlacesController < Admin::BaseController
  def update
    @place = Place.find(params[:id])

    if @place.update_attributes(place_params)
      # Redirect to OK page
    else
      # Show errors
    end
  end

  private

  def place_params
    params.require(:place)
      .permit(
        business_hours_attributes: [:day_of_week, :opening_time, :closing_time]
      )
  end
end

我有一个有点动态的表单,通过javascript呈现,用户可以在其中添加新的开放时间。提交这些开放时间时,我想总是替换旧的(如果存在的话)。目前,如果我通过params(例如)发送值:

place[business_hours][0][day_of_week]: 1
place[business_hours][0][opening_time]: 10:00 am
place[business_hours][0][closing_time]: 5:00 pm
place[business_hours][1][day_of_week]: 2
place[business_hours][1][opening_time]: 10:00 am
place[business_hours][1][closing_time]: 5:00 pm

......等等

这些新营业时间会添加到现有营业时间。有没有办法告诉rails总是替换营业时间,还是我每次都要手动清空控制器中的集合?

3 个答案:

答案 0 :(得分:8)

比特优化@robertokl提议的解决方案,以减少数据库查询的数量:

def business_hours_attributes=(*args)
  self.business_hours.clear
  super(*args)
end

答案 1 :(得分:3)

这是我能得到的最好的:

def business_hours_attributes=(*attrs)
  self.business_hours = []
  super(*attrs)
end

希望还不算太晚。

答案 2 :(得分:0)

你错过了business_hours的id:

def place_params
    params.require(:place)
      .permit(
        business_hours_attributes: [:id, :day_of_week, :opening_time, :closing_time]
      )
end

这就是为什么表单添加新记录而不是更新它。