【问题标题】:How to remove a field from params[:something]如何从参数中删除字段 [:something]
【发布时间】:2011-03-01 05:03:03
【问题描述】:

我的注册表单是用户模型的表单,它采用公司的字符串值。但是,我刚刚进行了更改,使用户属于公司。因此,我需要将 Company 的对象传递给 Users 模型。

我想使用表单中的字符串值来获取Company的对象:

@user.company = Company.find_by_name(params[:company])

我相信上述方法有效,但是当我调用时,表单正在将 :company(它是字符串)传递给模型:

@user = User.new(params[:user])

因此,我想知道(并且找不到如何)在将 :company 参数传递给 User 模型之前将其删除。

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    Rails 4/5 - 已编辑答案 (见 cmets)

    由于编写了这个问题,Rails 的新版本添加了 extract!except 例如:

    new_params = params.except[the one I wish to remove]
    

    这是一种更安全的方法,可以将所需的所有参数“抓取”到副本中,而不会破坏传入的原始参数(这不是一件好事,因为随着时间的推移,它会使代码的调试和维护变得非常困难)。

    或者你可以直接通过而不复制例如:

    @person.update(params[:person].except(:admin))
    

    extract!(具有 ! bang 运算符)将修改原始文件,因此请谨慎使用!

    原答案

    您可以使用Hash#delete 从哈希中删除键/值对:

    params.delete :company
    

    如果它包含在 params[:user] 中,那么你会使用这个:

    params[:user].delete :company
    

    【讨论】:

    • 我使用的是 Rails 4.0,而 model_params.delete :key_name 不起作用 - 知道为什么吗?
    • 从参数哈希中删除是一个非常糟糕的想法。在调试等过程中容易混淆人们......使用您传递的自定义哈希来分配属性,例如使用assin_params = params.dup.delete(:company)。永远不要直接从参数中删除
    • 我的意思是assign_params = params.dup; assign_params.delete(:company)
    • @Zorayr 我有同样的问题。对我来说,这是因为我的model_params 是一个函数,它从params 中提取了相关参数。因此,当您从 model_params 中删除 delete 时,您实际上只是从 model_params 返回的哈希中删除。
    • user_params 是一种方法,因此当您执行 user_params.delete(:this_param) 时,它会计算正确的哈希值,但随后对 user_params 的任何调用都会从头开始重新计算哈希值。这就是为什么@Gaul 说这是一个坏主意。在 Rails 5 中,您现在拥有 params.except 方法并且还可以提取!
    【解决方案2】:

    您可能应该使用 hash.except

    class MyController < ApplicationController
      def explore_session_params
        params[:explore_session].except(:account_id, :creator)
      end
    end
    

    它完成了两件事:允许您一次排除多个键,并且不修改原始哈希。

    【讨论】:

    • Rails 4 ActionController::Parameters 继承了Hash,所以除外或提取!会工作,在 Rails 5 中,它有 except 和提取! ActionController::Parameters 本身定义的方法
    • 我实际上在 UPDATE 方法中有这个哈希参数。除了以"-1" 为密钥的人外,我该怎么做。 {"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"VtY...", "brochure"=> {"title"=>"Hello world", "profilings_attributes" => {"-1"=>{"member_profile_id"=>"3"}, "0"=>{"percentage"=>"10.0", "description"=>"一些描述!", "_destroy"= >"false", "id"=>"10"}, "1"=>​​{...}}, "sponsorings_attributes"=> {"-1"=>{"sponsor_id"=>"2"}, "0"=>{"brochure_id"=>"1", "_destroy"=>"false", "id"=>"3"}, "1"=>​​{...}}, "commit"= >"Guardar", "id"=>"1"}
    【解决方案3】:

    实现这一点的正确方法是使用strong_params

    class UsersController < ApplicationController
      def create
        @user = User.new(user_params)
      end
    
      private
    
      def user_params
        params.require(:user).permit(:name, :age)
      end
    end
    

    这样你可以更好地控制哪些参数应该传递给模型

    【讨论】:

      【解决方案4】:
      respond_to do |format|
        if params[:company].present?
          format.html { redirect_to(:controller => :shopping, :action => :index) }
        else
          format.html
        end
      end
      

      这将从 url 中删除参数

      【讨论】:

        【解决方案5】:

        要删除你可以做一个备忘录

        def parameters
          @parameters ||= params.require(:root).permit(:foo, :bar)
        end
        

        现在你可以这样做了:

        parameteres.delete(:bar)
        
        parameters
        => <ActionController::Parameters {"foo" => "foo"} permitted: true>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多