【问题标题】:Strong parameters require multiple强参数需要多个
【发布时间】:2014-03-18 18:23:47
【问题描述】:

我收到一个 JSON 包,例如:

{
  "point_code" : { "guid" : "f6a0805a-3404-403c-8af3-bfddf9d334f2" }
}

我想告诉 Rails,point_codeguid 都是必需的,而不仅仅是允许的。

这段代码似乎可以工作,但我认为这不是一个好习惯,因为它返回一个字符串,而不是完整的对象:

params.require(:point_code).require(:guid)

有什么想法可以做到这一点吗?

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4


    【解决方案1】:

    我也有类似的需求,我所做的是

    def point_code_params
      params.require(:point_code).require(:guid) # for check require params
      params.require(:point_code).permit(:guid) # for using where hash needed
    end
    

    示例:

    def create
      @point_code = PointCode.new(point_code_params)
    end
    

    【讨论】:

    • 这是正确答案!为我工作(尽管我确实必须将第一行的 requires 分成两个 params.require() 调用
    • 不起作用,因为它会导致错误:私有方法 `require' 调用 "xxxxxxxx":String
    • @FloatingRock:在我的情况下,请求正文就像 { "id": 123, "name": "foo", "bar": "foobar" } 如何要求所有参数?
    • 你方法的第一行没有做任何事情。它不会改变状态或任何东西,返回值才是最重要的,它只是消失了,因为你没有将它分配给任何东西。你应该只需要第二行params.require(:point_code).permit(:guid)
    • 强参数的api太棒了
    【解决方案2】:

    截至 2015 年(RoR 5.0+),您可以将一组键传递给 rails 中的 require 方法:

    params.require([:point_code, :guid])

    http://api.rubyonrails.org/classes/ActionController/Parameters.html#method-i-require

    【讨论】:

    • 您的回答中未提及的是结果是一个数组。我警告其他刚刚接受您的回复并使用它的人(请注意,不要点击链接)。
    • 这应该如何工作?由于 .require 返回的是一个键数组而不是一个散列...... .permit 不能使用它,也不能使用 .new。 ?
    • 这不适用于嵌套参数,因为提出了问题。这是要求同一级别有多个键。
    【解决方案3】:

    Rails 文档 (https://api.rubyonrails.org/classes/ActionController/Parameters.html#method-i-require) 中提出的解决方案是:

    def point_code
      params.require(:point_code).permit(:guid).tap do |point_code_params|
        point_code_params.require(:guid) # SAFER
      end
    end
    

    【讨论】:

    • 请链接到相关文档!
    • 我添加了文档链接
    【解决方案4】:

    好的,不是很漂亮,但应该可以解决问题。假设你有参数 :foo、:bar 和 :baf,你想要一个 Thing 要求 all。你可以说

    def thing_params
      [:foo, :bar, :baf].each_with_object(params) do |key, obj|
        obj.require(key)
      end
    end
    

    each_with_object 返回 obj,初始化为 params。使用相同的参数 obj 您依次需要每个键,并最终返回对象。不漂亮,但对我有用。

    【讨论】:

    • 这段代码相当于def thing_params; params.require(:baf); end。请参阅 Vox 的comment above
    • 当您需要顶层键并返回类似对象的散列而不是值数组时,此答案最能发挥作用。
    【解决方案5】:

    require 接受一个参数。因此,除非您覆盖 require 方法,否则您无法传递多个键。您可以在操作中添加一些额外的逻辑来实现您想要的:

    def action
      raise ActionController::ParameterMissing.new("param not found: point_code") if point_params[:point_code].blank?
      raise ActionController::ParameterMissing.new("param not found: guid") if point_params[:point_code][:guid].blank?
    
      <do your stuff>
    end
    
    def point_params
      params.permit(point_code: :guid)
    end
    

    【讨论】:

      【解决方案6】:

      这个问题出现在我的谷歌搜索不同的情况下,即当使用“multiple:true”时:

      <%= form.file_field :asset, multiple: true %>
      

      这与问题完全不同。但是,为了提供帮助,这里有一个 Rails 5+ 中的工作示例:

      form_params = params.require(:my_profile).permit({:my_photos => []})
      

      【讨论】:

        【解决方案7】:

        虽然很多这些答案向您展示了如何获得您所要求的东西,但我想补充这些答案并建议您使用before_action。如果缺少所需的参数,require 将自动返回 400 错误

        class SomeController < ApplicationController
          before_action :ensure_valid_params, only: :index
        
          def index
            # do your stuff
          end
        
        private
        
          def ensure_valid_params
            params.require(:some_required_param)
          end
        end
        

        【讨论】:

          猜你喜欢
          • 2015-12-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-06-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多