Ruby on rails 如何允许具有强参数的数组

Ruby 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

我有一个功能正常的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_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
    不需要在末尾,但需要确保有有效的Ruby
    params.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: [] )