Rails 4: collection_check_box 错误
Rails 4: collection_check_box error
我正在构建一个用于启动新活动的表单。通过此活动,您可以选择 Zip 文件 and/or 一些 PDF 文件。 Zip 和 PDF 文件都存储在上传 table 中。
到目前为止,我似乎可以选择一个 Zip 文件,但是,一旦我为 PDF 添加 collection_check_box
,创建一个活动,我收到以下错误...
expected Array (got String) for param `upload_ids'
我的表格是这样的..
<%= form_for @campaign, url: {action: "create"} do |f| %>
<%= f.label :name, class: "right-label" %>
<%= f.text_field :name %>
<%= f.label :comment, "Comments" %>
<%= f.text_area :comment %>
<%= f.label :zip_file, class: "right-label" %>
<%= f.collection_select :upload_ids, Upload.where(file_type: ".zip"), :id, :file_name, include_blank: "Include a Zip File" do |b| %>
<%= b.option + File.basename(b.text, '.*') %>
<% end %>
<%= f.label :pdf_files %>
<ul><%= f.collection_check_boxes :upload_ids, Upload.where(file_type: ".pdf"), :id, :file_name do |b| %>
<li><%= b.label do %>
<%= b.check_box + File.basename(b.text,'.*') %>
</li>
<% end %>
<% end %>
</ul>
这是根据请求在服务器上显示的错误。
[2015-06-01 14:50:57] ERROR Rack::Utils::ParameterTypeError: expected Array (got String) for param `upload_ids'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/utils.rb:142:in `normalize_params'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/utils.rb:156:in `normalize_params'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/utils.rb:117:in `block in parse_nested_query'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/utils.rb:114:in `each'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/utils.rb:114:in `parse_nested_query'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/request.rb:369:in `parse_query'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/request.rb:215:in `POST'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/methodoverride.rb:39:in `method_override_param'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/methodoverride.rb:27:in `method_override'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/methodoverride.rb:15:in `call'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/runtime.rb:18:in `call'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/activesupport-4.2.1/lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/lock.rb:17:in `call'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/actionpack-4.2.1/lib/action_dispatch/middleware/static.rb:113:in `call'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/sendfile.rb:113:in `call'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/railties-4.2.1/lib/rails/engine.rb:518:in `call'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/railties-4.2.1/lib/rails/application.rb:164:in `call'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/lock.rb:17:in `call'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/content_length.rb:15:in `call'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/handler/webrick.rb:89:in `service'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/2.2.0/webrick/httpserver.rb:138:in `service'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/2.2.0/webrick/httpserver.rb:94:in `run'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/2.2.0/webrick/server.rb:294:in `block in start_thread'
编辑
如果我删除其中一个集合块(zip 或 pdf),我的活动创建就成功了。
上面的Zip文件和PDF文件选择方法好像和我的"upload_ids"有冲突。即使我的模型关系表明活动 has_many: uploads, through: uploadable
和 has_many: uploadable
,它也在尝试接受两者 - Zip 和 PDF/s - upload_id
的一个实例。
我仍然不确定如何解决这个问题。感谢任何帮助。
controllers/campaigns_controller.rb
class CampaignsController < ApplicationController
def index
@campaigns = Campaign.all.order("created_at DESC")
end
def new
@campaign = Campaign.new
end
def create
@campaign = Campaign.new(campaign_params)
if @campaign.save
flash[:success] = "Campaign Successfully Launched!"
redirect_to @campaign
else
flash[:error] = "There was a problem launching your Campaign."
redirect_to new_campaign_path
end
end
def show
@campaign = Campaign.find(params[:id])
end
private
def campaign_params
params.require(:campaign).permit(:name, :comment)
end
end
log/development.log
Started GET "/campaigns/new" for ::1 at 2015-06-01 18:54:19 -0700
Processing by CampaignsController#new as HTML
[1m[35mUpload Load (0.2ms)[0m SELECT "uploads".* FROM "uploads"
[1m[36mUpload Load (0.3ms)[0m [1mSELECT "uploads".* FROM "uploads" WHERE "uploads"."file_type" = [0m [["file_type", ".zip"]]
[1m[35mUpload Load (0.1ms)[0m SELECT "uploads".* FROM "uploads" WHERE "uploads"."file_type" = [["file_type", ".pdf"]]
Rendered campaigns/_form.html.erb (6.6ms)
Rendered campaigns/new.html.erb within layouts/application (7.5ms)
Rendered layouts/_header.html.erb (0.2ms)
Rendered layouts/_footer.html.erb (0.0ms)
Completed 200 OK in 82ms (Views: 80.4ms | ActiveRecord: 0.5ms)
更新#1
另一位开发者朋友指出,我不能同时对 collection_selects
使用 "upload_ids"。这在我上面的实验中也很明显。那么我如何允许用户将该对象与来自单独 model/table 的其他 2 个对象相关联?
我将一个 collection_select
对象参数更改为 uploadable_ids
但这是我放置的随机名称。我不知道该把什么作为那个参数。现在我收到了 flash[:error] "There was a problem launching your Campaign."
更新 #2
我已经尝试了很多建议,包括这篇文章中的建议,但仍在努力使它起作用。 select_tag
抛出 undefined method
,所以暂时我只使用 select
。我尝试添加 upload_ids[]
但被抛出一个错误,需要更多参数。
我也对是否需要向我的控制器添加任何东西感到困惑。当我决定查询哪个 Campaign 与哪些文件关联时,我的 Active Record 关联是否足够?
这是表格的当前状态的 zip 和 pdf 部分..
<%= f.label :data_file, class: "right-label" %>
<%= f.select :upload_ids,
options_from_collection_for_select(
Upload.where(file_type: ".zip"), :id, :file_name),
{include_blank: "Include a Zip File"}, {mulitple: true} %>
<%= f.label :additional_files %>
<%= f.collection_check_boxes(:upload_ids,
Upload.where(file_type: ".pdf"), :id, :file_name,
{ mulitple: true }) do |b| %>
<%= b.label do %>
<%= b.check_box + File.basename(b.text,'.*') %>
<% end %>
<% end %>
如果有任何补充帮助,这里是模型关系:
class Campaign < ActiveRecord::Base
has_many has_many :uploadable
has_many :uploads, through: :uploadable
end
class Uploadable < ActiveRecord::Base
belongs_to :campaign
belongs_to :upload
end
class Upload < ActiveRecord::Base
has_many :uploadable
has_many :campaigns, through: :uploadable
end
我看到的主要问题是您的复选框正在提交一个数组参数(您可以 select 多个复选框)但是您的 collection_select
正在尝试提交一个奇异值。两者的混合是导致 Rack::Utils::ParameterTypeError
的原因
您的 uploads
关联是 has_many 因此使用数组参数是正确的做法。您可以做的最简单的事情是通过添加 multiple: true
选项使 select 成为多项选择。请注意,这必须放在您的 include_blank
选项的单独哈希中。
要保留一个单独的 select,我认为您需要向下调用 select_tag 并指定 upload_ids[]
作为输入名称。您仍然可以使用 options_from_collection_for_select
来生成选项标签。
我正在构建一个用于启动新活动的表单。通过此活动,您可以选择 Zip 文件 and/or 一些 PDF 文件。 Zip 和 PDF 文件都存储在上传 table 中。
到目前为止,我似乎可以选择一个 Zip 文件,但是,一旦我为 PDF 添加 collection_check_box
,创建一个活动,我收到以下错误...
expected Array (got String) for param `upload_ids'
我的表格是这样的..
<%= form_for @campaign, url: {action: "create"} do |f| %>
<%= f.label :name, class: "right-label" %>
<%= f.text_field :name %>
<%= f.label :comment, "Comments" %>
<%= f.text_area :comment %>
<%= f.label :zip_file, class: "right-label" %>
<%= f.collection_select :upload_ids, Upload.where(file_type: ".zip"), :id, :file_name, include_blank: "Include a Zip File" do |b| %>
<%= b.option + File.basename(b.text, '.*') %>
<% end %>
<%= f.label :pdf_files %>
<ul><%= f.collection_check_boxes :upload_ids, Upload.where(file_type: ".pdf"), :id, :file_name do |b| %>
<li><%= b.label do %>
<%= b.check_box + File.basename(b.text,'.*') %>
</li>
<% end %>
<% end %>
</ul>
这是根据请求在服务器上显示的错误。
[2015-06-01 14:50:57] ERROR Rack::Utils::ParameterTypeError: expected Array (got String) for param `upload_ids'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/utils.rb:142:in `normalize_params'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/utils.rb:156:in `normalize_params'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/utils.rb:117:in `block in parse_nested_query'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/utils.rb:114:in `each'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/utils.rb:114:in `parse_nested_query'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/request.rb:369:in `parse_query'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/request.rb:215:in `POST'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/methodoverride.rb:39:in `method_override_param'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/methodoverride.rb:27:in `method_override'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/methodoverride.rb:15:in `call'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/runtime.rb:18:in `call'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/activesupport-4.2.1/lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/lock.rb:17:in `call'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/actionpack-4.2.1/lib/action_dispatch/middleware/static.rb:113:in `call'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/sendfile.rb:113:in `call'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/railties-4.2.1/lib/rails/engine.rb:518:in `call'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/railties-4.2.1/lib/rails/application.rb:164:in `call'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/lock.rb:17:in `call'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/content_length.rb:15:in `call'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rack-1.6.1/lib/rack/handler/webrick.rb:89:in `service'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/2.2.0/webrick/httpserver.rb:138:in `service'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/2.2.0/webrick/httpserver.rb:94:in `run'
/Users/Josh/.rbenv/versions/2.2.2/lib/ruby/2.2.0/webrick/server.rb:294:in `block in start_thread'
编辑
如果我删除其中一个集合块(zip 或 pdf),我的活动创建就成功了。
上面的Zip文件和PDF文件选择方法好像和我的"upload_ids"有冲突。即使我的模型关系表明活动 has_many: uploads, through: uploadable
和 has_many: uploadable
,它也在尝试接受两者 - Zip 和 PDF/s - upload_id
的一个实例。
我仍然不确定如何解决这个问题。感谢任何帮助。
controllers/campaigns_controller.rb
class CampaignsController < ApplicationController
def index
@campaigns = Campaign.all.order("created_at DESC")
end
def new
@campaign = Campaign.new
end
def create
@campaign = Campaign.new(campaign_params)
if @campaign.save
flash[:success] = "Campaign Successfully Launched!"
redirect_to @campaign
else
flash[:error] = "There was a problem launching your Campaign."
redirect_to new_campaign_path
end
end
def show
@campaign = Campaign.find(params[:id])
end
private
def campaign_params
params.require(:campaign).permit(:name, :comment)
end
end
log/development.log
Started GET "/campaigns/new" for ::1 at 2015-06-01 18:54:19 -0700
Processing by CampaignsController#new as HTML
[1m[35mUpload Load (0.2ms)[0m SELECT "uploads".* FROM "uploads"
[1m[36mUpload Load (0.3ms)[0m [1mSELECT "uploads".* FROM "uploads" WHERE "uploads"."file_type" = [0m [["file_type", ".zip"]]
[1m[35mUpload Load (0.1ms)[0m SELECT "uploads".* FROM "uploads" WHERE "uploads"."file_type" = [["file_type", ".pdf"]]
Rendered campaigns/_form.html.erb (6.6ms)
Rendered campaigns/new.html.erb within layouts/application (7.5ms)
Rendered layouts/_header.html.erb (0.2ms)
Rendered layouts/_footer.html.erb (0.0ms)
Completed 200 OK in 82ms (Views: 80.4ms | ActiveRecord: 0.5ms)
更新#1
另一位开发者朋友指出,我不能同时对 collection_selects
使用 "upload_ids"。这在我上面的实验中也很明显。那么我如何允许用户将该对象与来自单独 model/table 的其他 2 个对象相关联?
我将一个 collection_select
对象参数更改为 uploadable_ids
但这是我放置的随机名称。我不知道该把什么作为那个参数。现在我收到了 flash[:error] "There was a problem launching your Campaign."
更新 #2
我已经尝试了很多建议,包括这篇文章中的建议,但仍在努力使它起作用。 select_tag
抛出 undefined method
,所以暂时我只使用 select
。我尝试添加 upload_ids[]
但被抛出一个错误,需要更多参数。
我也对是否需要向我的控制器添加任何东西感到困惑。当我决定查询哪个 Campaign 与哪些文件关联时,我的 Active Record 关联是否足够?
这是表格的当前状态的 zip 和 pdf 部分..
<%= f.label :data_file, class: "right-label" %>
<%= f.select :upload_ids,
options_from_collection_for_select(
Upload.where(file_type: ".zip"), :id, :file_name),
{include_blank: "Include a Zip File"}, {mulitple: true} %>
<%= f.label :additional_files %>
<%= f.collection_check_boxes(:upload_ids,
Upload.where(file_type: ".pdf"), :id, :file_name,
{ mulitple: true }) do |b| %>
<%= b.label do %>
<%= b.check_box + File.basename(b.text,'.*') %>
<% end %>
<% end %>
如果有任何补充帮助,这里是模型关系:
class Campaign < ActiveRecord::Base
has_many has_many :uploadable
has_many :uploads, through: :uploadable
end
class Uploadable < ActiveRecord::Base
belongs_to :campaign
belongs_to :upload
end
class Upload < ActiveRecord::Base
has_many :uploadable
has_many :campaigns, through: :uploadable
end
我看到的主要问题是您的复选框正在提交一个数组参数(您可以 select 多个复选框)但是您的 collection_select
正在尝试提交一个奇异值。两者的混合是导致 Rack::Utils::ParameterTypeError
您的 uploads
关联是 has_many 因此使用数组参数是正确的做法。您可以做的最简单的事情是通过添加 multiple: true
选项使 select 成为多项选择。请注意,这必须放在您的 include_blank
选项的单独哈希中。
要保留一个单独的 select,我认为您需要向下调用 select_tag 并指定 upload_ids[]
作为输入名称。您仍然可以使用 options_from_collection_for_select
来生成选项标签。