rails form_for创建新条目而不是更新

时间:2015-06-04 15:11:58

标签: ruby-on-rails form-for

我正在使用form_for来创建新条目。

在我设置的控制器中:

def create_ab_campaign
  @campaign = Campaign.find_by(id: params[:id],  account_id: current_account.id)
  @campaign_id = params[:id]
end

在我看来:

<%= form_for (@campaign), :url => {:controller => "campaigns", :action => "create_new_ab_campaign"} do |f| %>
<div class="form-group">
<%= f.label :name, "name", class: "control-label" %>
<%= f.text_field :name, class: "form-control", placeholder: "name" %>
</div>
<%= f.submit "Save Settings" %>

在提交时,我希望创建新条目,而不是更新现有条目。

我在控制器中执行了以下操作:

def create_ab_campaign_new
  @campaign_new = Campaign.new(create_a_new_ab_campaign)
   if @campaign_new.save
    redirect_to(:controller =>"campaigns", :action =>"index")
   else
    redirect_to(:action =>"new")
   end
end

private
  def create_a_new_ab_campaign
    params.require(:campaign).permit(:name)
  end

我得到以下内容: CampaignsController#update中的NoMethodError

它仍尝试使用更新而不是“create_a_new_ab_campaign”

我使用更新来更新记录 - 这一切都很好。

def update
  @campaign = Campaign.find_by(id:params[:id], account_id: current_account.id)
  @new = create_new_campaign
  if @campaign.update_attributes(@new)
    redirect_to(:controller =>"campaigns", :action =>"index")
  else
    render 'edit'
  end
end

但是如上所述,我不想更新/编辑,而是想做另一个案例并从记录中创建一个新条目。

非常感谢你的帮助!

更新:

完整错误日志:

CampaignsController#update中的NoMethodError nil的未定义方法`update_attributes':NilClass

提取的来源(第124行): 122 123 124 125 126 127

@new = create_new_campaign
@new[:page_type].delete_if{ |x| x.empty? }
if @campaign.update_attributes(@new)
  redirect_to(:controller =>"campaigns", :action =>"index")
else
  render 'edit'

Rails.root:/ Users / sschindler / demostore

应用程序跟踪|框架跟踪|完整追踪 app / controllers / campaigns_controller.rb:124:在`update'

更新路线

路线:

发布“campaign / create_new_ab_campaign”

获取“campaign / create_new_ab_campaign”

发布“/ campaigns /:id / edit”=&gt; “广告活动#编辑”

获取“/ campaigns /:id / edit”=&gt; “广告活动#编辑”

发布“/ campaigns / create_ab_campaign”=&gt; “广告活动#create_ab_campaign”

获取“/ campaigns / create_ab_campaign”=&gt; “广告活动#create_ab_campaign”

发布“/ campaigns /:id”=&gt; “广告活动#编辑”

发布“/ campaigns /:id”=&gt; “广告活动#新的”

获取“/ campaigns /:id”=&gt; “广告活动#编辑”

获取'广告系列/展示'

获取'广告系列/索引'

发布'/ campaign / edit'

获取'/ campaigns / edit'

2 个答案:

答案 0 :(得分:0)

我假设您的create_ab_campaign是您的新路线,而create_ab_campaign_new是您的邮寄路线。虽然我很困惑,因为params[:id]

中的值为#create_ab_campaign

从它的外观来看,您的表单正在尝试更新,因为您正在传递form_for已创建的广告系列变量:@campaign = Campaign.find_by(...)

rails form_for将检查对象是否是数据库中的实例,或者它是否只是一个新模型。如果它已经被创建,它将PATCH到你的更新路线;如果它是一个新的模型(但没有创建),它将POST到你的创建路径。

#new路线中,您需要将@campaign分配给Campaign.new(account_id:current_account.id),而不是找到已经制作过的。{/ p>

<强>更新
根据您的注释,您希望复制模型,更改某些字段并将其另存为新记录。在这种情况下,您需要将要复制的活动模型的ID发送到表单,这样您就可以在创建路径中检索它,使用model.dup,使用params修改它,然后保存。

def create_ab_campaign
  @campaign = Campaign.new
  @campaign_id = params[:id]
end

添加隐藏字段以形成

<%= form_for (@campaign), :url => {:controller => "campaigns", :action => "create_new_ab_campaign"} do |f| %>
<div class="form-group">
<%= hidden_field_tag :campaign_id, @campaign_id
<%= f.label :name, "name", class: "control-label" %>
<%= f.text_field :name, class: "form-control", placeholder: "name" %>
</div>
<%= f.submit "Save Settings" %>

创建路线
复制广告系列,进行修改并检查有效性。请确保不要在此型号上进行唯一性验证,否则会遇到一些麻烦

def create_ab_campaign_new
  @campaign_new = Campaign.find(params[:campaign_id]).dup
  @campaign_new.update(create_a_new_ab_campaign)
   if @campaign_new.save
    redirect_to(:controller =>"campaigns", :action =>"index")
   else
    redirect_to(:action =>"new")
   end
end

答案 1 :(得分:0)

看起来你正在混合你的VERBS

`post "campaigns/create_new_ab_campaign"`

是一个帖子,

= form_for (@campaign), :url => {:controller => "campaigns", :action => "create_new_ab_campaign"} do |f|

是一个PUT。尝试更改为

在route.rb中:

match 'create_new_ab_campaign', to 'campaigns#create_new_ab_campaign', via: :post

然后

=form_for(@campaign), url: :create_new_ab_campaign, method: 'POST' do |f|

基本上如果在新对象上调用form_for,则表单提交方法默认为POST,如果您在现有对象上使用,则表单提交方法默认为{{ 1}}。这就是为什么它一直在寻找更新。要更改此设置,请将PUT/PATCH关键字添加到表单构建器。

进一步阅读:http://www.restapitutorial.com/lessons/httpmethods.html