1

所以我正在重写/升级一个 3.0 应用程序,它使用基于这个 pro Railscast http://railscasts.com/episodes/403-dynamic-forms的动态字段。

它加载动态字段的方式是通过以下代码:

  <%= f.hidden_field :tour_type_id %>

  <%= f.fields_for :options, OpenStruct.new(@trip.options) do |builder| %>
     <% @trip.tour_type.type_fields.where(:variable => false).each do |field| %>
           <%= render "type_fields", field: field, f: builder %>
      <% end %>
    <% end %>

这是正确呈现 html。

当我通过控制台执行创建时,我为 :options 传递的哈希值正确保存。但是,当我通过表单提交值时,它会将哈希值保存为 nil。

我认为这可能是因为我在控制器中拥有强大的参数。

  def trip_params
     params.require(:trip).permit(:options => {:id => :value})
  end

我也试过

  def trip_params
     params.require(:trip).permit(:options => {})
  end

参数在 rails 服务器日志中看起来不错,但不知何故在更新发生之前,选项的值被设置为 nil

  Processing by TripsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"...", "trip"=>{"options"=>{"1"=>"400"}}, "commit"=>"Update Trip", "id"=>"1"}

 SQL (1.0ms)  UPDATE "trips" SET "updated_at" = $1, "options" = $2 WHERE "trips"."id" = 1  [["updated_at", Mon, 26 Aug 2013 05:13:35 UTC +00:00], ["options", "--- !ruby/hash:ActionController::Parameters\n'1': \n"]]

我还在模型中添加了序列化操作

 class Trip < ActiveRecord::Base
   serialize :options, Hash
 end

我真的不知道为什么这段代码在 Rails v 4、Ruby V 1.9.3 中不起作用。

此代码是根据动态表单 RailsCast 建模的。

编辑:

我尝试了此处概述的解决方案http://guides.rubyonrails.org/action_controller_overview.html#outside-the-scope-of-strong-parameters

def trip_params
  params.require(:trip).permit(
    :admin_name, 
    :brochure_title, 
    :description, 
    :organized_by, 
    :start_date, 
    :end_date, 
    :tour_type_id, 
    :pay_by, 
    :extension
  ).tap do |whitelisted|
    whitelisted[:options] = params[:trip][:options]
  end
end

我现在得到一个发现的未经许可的参数:选项错误。

4

1 回答 1

0

似乎strong_parameters不支持允许使用任意键进行散列,我认为这是有充分理由的……</p>

在 Rails github repo 上建议了一个解决方案:https ://github.com/rails/rails/issues/9454#issuecomment-14167664和RailsGuides http://guides.rubyonrails.org/action_controller_overview.html#outside-the-强参数范围

对于你的情况,它会是这样的

params.require(:trip).permit(:foo, :bar, :baz).tap do |whitelisted|
  whitelisted[:options] = params[:trip][:options]
end

如果options是您唯一的属性,Trip那么这与

params.require(:trip).permit!
于 2013-08-26T12:05:02.067 回答