Ruby on rails 如何允许具有强参数的数组
我有一个功能正常的Rails 3应用程序,它使用了has_许多:通过关联而不是,因为我将其重新制作为Rails 4应用程序,允许我在Rails 4版本中保存关联模型的ID 这三个相关模型对于两个版本是相同的 分类.rbRuby on rails 如何允许具有强参数的数组,ruby-on-rails,arrays,strong-parameters,Ruby On Rails,Arrays,Strong Parameters,我有一个功能正常的Rails 3应用程序,它使用了has_许多:通过关联而不是,因为我将其重新制作为Rails 4应用程序,允许我在Rails 4版本中保存关联模型的ID 这三个相关模型对于两个版本是相同的 分类.rb class Categorization < ActiveRecord::Base belongs_to :question belongs_to :category end Category.rb has_many :categorizations has_m
class Categorization < ActiveRecord::Base
belongs_to :question
belongs_to :category
end
Category.rb
has_many :categorizations
has_many :questions, through: :categorizations
在这两个应用程序中,类别ID都被传递到创建操作中,如下所示
"question"=>{"question_content"=>"How do you spell car?", "question_details"=>"blah ", "category_ids"=>["", "2"],
在Rails 3应用程序中,当我创建一个新问题时,它会插入问题表,然后插入分类表
SQL (82.1ms) INSERT INTO "questions" ("accepted_answer_id", "city", "created_at", "details", "province", "province_id", "question", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) [["accepted_answer_id", nil], ["city", "dd"], ["created_at", Tue, 14 May 2013 17:10:25 UTC +00:00], ["details", "greyound?"], ["province", nil], ["province_id", 2], ["question", "Whos' the biggest dog in the world"], ["updated_at", Tue, 14 May 2013 17:10:25 UTC +00:00], ["user_id", 53]]
SQL (0.4ms) INSERT INTO "categorizations" ("category_id", "created_at", "question_id", "updated_at") VALUES (?, ?, ?, ?) [["category_id", 2], ["created_at", Tue, 14 May 2013 17:10:25 UTC +00:00], ["question_id", 66], ["updated_at", Tue, 14 May 2013 17:10:25 UTC +00:00]]
在rails 4应用程序中,在处理QuestionController#create中的参数后,我在服务器日志中得到了这个错误
Unpermitted parameters: category_ids
问题只会被插入到问题表中
(0.2ms) BEGIN
SQL (67.6ms) INSERT INTO "questions" ("city", "created_at", "province_id", "question_content", "question_details", "updated_at", "user_id") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["city", "dd"], ["created_at", Tue, 14 May 2013 17:17:53 UTC +00:00], ["province_id", 3], ["question_content", "How's your car?"], ["question_details", "is it runnign"], ["updated_at", Tue, 14 May 2013 17:17:53 UTC +00:00], ["user_id", 12]]
(31.9ms) COMMIT
虽然我没有将category_id存储在Questions模型上,但我将category_id设置为Questions_控制器中允许的参数
def question_params
params.require(:question).permit(:question_details, :question_content, :user_id, :accepted_answer_id, :province_id, :city, :category_ids)
end
有人能解释一下我该如何保存分类ID吗?注意,两个应用程序的categories_controller.rb中都没有创建操作
这三个表在两个应用程序中都是相同的
create_table "questions", force: true do |t|
t.text "question_details"
t.string "question_content"
t.integer "user_id"
t.integer "accepted_answer_id"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "province_id"
t.string "city"
end
create_table "categories", force: true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "categorizations", force: true do |t|
t.integer "category_id"
t.integer "question_id"
t.datetime "created_at"
t.datetime "updated_at"
end
更新
这是Rails 3应用程序中的创建操作
def create
@question = Question.new(params[:question])
respond_to do |format|
if @question.save
format.html { redirect_to @question, notice: 'Question was successfully created.' }
format.json { render json: @question, status: :created, location: @question }
else
format.html { render action: "new" }
format.json { render json: @question.errors, status: :unprocessable_entity }
end
end
end
这是Rails 4应用程序的创建操作
def create
@question = Question.new(question_params)
respond_to do |format|
if @question.save
format.html { redirect_to @question, notice: 'Question was successfully created.' }
format.json { render json: @question, status: :created, location: @question }
else
format.html { render action: "new" }
format.json { render json: @question.errors, status: :unprocessable_entity }
end
end
end
这就是问题参数法
private
def question_params
params.require(:question).permit(:question_details, :question_content, :user_id, :accepted_answer_id, :province_id, :city, :category_ids)
end
这似乎是文档的相关部分:
允许的标量类型有字符串、符号、NilClass、数值、TrueClass、FalseClass、日期、时间、日期时间、StringIO、IO、,
ActionDispatch::Http::UploadedFile和Rack::Test::UploadedFile
要声明params中的值必须是允许的标量值数组,请将键映射到空数组:
params.permit(:id => [])
在我的应用程序中,类别ID以数组形式传递给创建操作
"category_ids"=>["", "2"],
因此,在声明强参数时,我显式地将category_id设置为数组
params.require(:question).permit(:question_details, :question_content, :user_id, :accepted_answer_id, :province_id, :city, :category_ids => [])
现在效果很好
(重要提示:正如@Lenart在注释中所指出的,数组声明必须位于属性列表的末尾,否则会出现语法错误。)如果您希望允许哈希数组(或者从JSON的角度看
对象数组)
这里需要注意两点:
array
应该是permit
方法的最后一个参数
您应该在数组中指定散列的键,否则会得到一个错误未经允许的参数:array
,在这种情况下很难调试
如果您有如下哈希结构:
Parameters: {"link"=>{"title"=>"Something", "time_span"=>[{"start"=>"2017-05-06T16:00:00.000Z", "end"=>"2017-05-06T17:00:00.000Z"}]}}
我就是这样让它工作的:
params.require(:link).permit(:title, time_span: [[:start, :end]])
应该是
params.permit(:id => [])
此外,由于rails版本4+,您可以使用:
params.permit(id: [])
我还不能发表评论,但在“陌生人”解决方案之后,您还可以继续嵌套,以防有值为数组的键。像这样:
filters: [{ name: 'test name', values: ['test value 1', 'test value 2'] }]
这项工作:
params.require(:model).permit(filters: [[:name, values: []]])
当您想要允许多个数组字段时,您必须在允许的同时最后列出数组字段,如下所示-
params.require(:questions).permit(:question, :user_id, answers: [], selected_answer: [] )
(这很有效)两个应用程序中的创建操作是什么样子的?@bennick我添加了两个创建操作。我还注意到数组的声明应该在属性列表的末尾。否则我会得到一个语法错误语法错误,意外'”,预期=>
数组声明(嵌套参数)位于末尾的原因是ActionController::Parameters.permit预期每个参数都是哈希或符号。Ruby magic会将方法调用结束时的所有键值对转换为一个散列,但如果在方法调用中将符号与键值对混合,Ruby将不知道该怎么办。如果category\u id
不是数组(例如,发送了字符串),那么rails完全失控,并引发错误类型错误:预期数组(Get string)对于参数'category_id'
,这是rails中的错误吗?编辑:是的:@Lenart谢谢,我以为我疯了。这至少应该出现在强参数中README@Lenart若要避免语法错误,可以将其添加为哈希params.permit(:foo,{bar:[]},:zoo)
。不支持数组的数组:array
不需要在末尾,但需要确保有有效的Rubyparams.permit(:foo,数组:[:key1,:key2],:bar)
将不是有效的ruby,因为解释器希望在第一个集合之后有哈希键:值对。要拥有有效的Ruby,您需要params.permit(:foo,{array:[:key1,:key2]},:bar)
您是一个冠军!这个答案应该用mastBlasta的评论来编辑(我试过了,但是建议的编辑队列已经满了),请不要说数组应该是permit方法的最后一个参数,您所说的apply for Rails v4+的哈希语法实际上是Ruby 1.9及更新版本中可用的语法,而不是Rails框架(尽管Rails 4需要Ruby 1.9.3或更新版本)这是不对的@MatiasElorriaga。。。参见mastaBlasta对Brian回答的评论,或
params.require(:model).permit(filters: [[:name, values: []]])
params.require(:questions).permit(:question, :user_id, answers: [], selected_answer: [] )