Rails accepted_nested_attributes_for始终创建嵌套模型,但不更新它们

时间:2013-08-29 21:50:42

标签: ruby-on-rails ruby-on-rails-3 activerecord

鉴于以下内容:

class WebsitesController < ApplicationController
  # POST /websites/save
  # POST /websites/save.json
  def save
    Website.exists?(name: params[:website][:name]) ? update : create
  end

  # POST /websites
  # POST /websites.json
  def create
    @server  = Server.find_or_create_by_name(params[:server_id])
    @website = @server.websites.new(params[:website])

    #etc... @website.save
  end

  # PUT /websites/1
  # PUT /websites/1.json
  def update
    @website = Website.find_by_name(params[:website][:name])

    #etc... @website.update_attributes
  end
end

客户端没有这些模型的任何ID

仅发送的请求包含names,但不包含ids

以下型号

class Website < ActiveRecord::Base
  serialize :website_errors

  attr_accessible :plugins_attributes
  has_many :plugins

  accepts_nested_attributes_for :plugins
end

class Plugin < ActiveRecord::Base
  belongs_to :website
end

当我向POST发出/websites/save.json请求时,如果Website存在,Plugins会正确更新,但属于它的update始终会重新创建,从而导致重复的内容在数据库中。为什么会这样?我重定向到调用update_attributes的{​​{1}}操作,那么它怎么能不更新呢?我认为这是因为请求没有提供ID。

我可以让Controller听取plugin_name而不是plugin_id吗?

1 个答案:

答案 0 :(得分:1)

修改您的控制器以使其:

def update
  @website = Website.find_by_name(params[:website][:name])
  if @website.update(params)
    redirect_to website_path(@website)
  else
    render :edit
  end
end

此外,如果您正在使用strong_parameters,则您需要在控制器底部使用此功能:

params.require(:website).
  permit(
    :name,
    ...,
    plugins_attributes: [
      :name,
      ...,
    ]
  )
end