【问题标题】:Why am I getting an undefined method `deep_merge' for ActionController::Parameters error?为什么我会因为 ActionController::Parameters 错误得到一个未定义的方法“deep_merge”?
【发布时间】:2018-07-06 09:17:41
【问题描述】:

在我的 Rails 5 应用程序中,我试图在控制器中执行此操作:

  def create
    company_params = params.require(:company).permit(
      :name,
      :email,
      :people_attributes => [
        :first_name,
        :last_name
      ]
    ).deep_merge(
      :creator_id => current_user.id,
      :people_attributes => [
        :creator_id => current_user.id
      ]
    )
    @company = current_account.companies.build(company_params)
    if @company.save
      flash[:success] = "Company created."
      redirect_to companies_path
    else
      render :new
    end
  end

由于某种原因,我收到了这个错误:

ActionController::Parameters:0x007fa24c39cfb0 的未定义方法 `deep_merge'

我在这里错过了什么?

【问题讨论】:

    标签: ruby-on-rails ruby actioncontroller


    【解决方案1】:

    我在这里错过了什么?

    paramsActionController::Parameters 的一个实例。它不是哈希。不过,它有一些合并方法。

    params.methods.grep(/merge/)
    => [:reverse_merge!, :reverse_merge, :merge!, :merge]
    

    如果您想要deep_merge,请以某种方式将您的参数转换为哈希。

    【讨论】:

    • 好的,谢谢!那么this answer 是错误的。基本上,我想要的是将creator_id 合并到people_attributes 中。有没有使用deep_merge 的替代方法?
    • @Tintin81:现在错了。也许两年前 ActionController::Parameters Hash的子类。
    • @Tintin81:“有没有使用 deep_merge 的替代方法?” - deep_merge 在这里看起来是一个合适的工具。只要确保您对哈希进行操作即可。 params.require(:foo).permit(:bar).as_json.deep_merge(...) 或类似的东西。
    • 不幸的是,无法让它工作。使用 .as_json.deep_merge 时不会保存 first_namelast_name 属性。
    【解决方案2】:

    即使在请求周期中修改参数不是一个好习惯,但如果您想这样做,总有一个 .to_hash.deep_merge 选项供您从参数实例检索哈希。

    【讨论】:

    • “在请求周期中修改参数不是一个好习惯”——你在说什么?这就是强参数的全部存在理由
    • permit 返回一个包含这些键的新哈希,因此您不会修改真正的 params 变量。我想你在这里误解了modify 的定义和强参数中使用的whitelisting 技术。
    • 有一篇关于这个的旧文章 :) rails-bestpractices.com/posts/2013/09/18/…
    • 哈,或者可能是你误解了一些东西:) deep_merge 也返回一个新的哈希,保持原来的结构不变。
    • @Tintin81:你将数组传递给 deep_merge 中的 people_attributes。应该是一个哈希。
    【解决方案3】:

    好的,我无法让deep_merge 工作,所以我最终这样做了:

      def create
        company_params = params.require(:company).permit(
          :name, 
          :email,
          :people_attributes => [
            :first_name,
            :last_name
          ]
        )
        @company = current_account.companies.build(company_params)
        @company.creator = current_user
        @person = @company.people.last
        @person.account = current_account
        @person.creator = current_user
        if @company.save
          flash[:success] = "Company created."
          redirect_to companies_path
        else
          render :new
        end
      end
    

    不确定这是好还是坏的做法。感谢您的反馈!

    【讨论】:

    • 还可以。不是最漂亮的 ruby​​ 代码,但它可以工作,这才是最重要的 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-22
    • 1970-01-01
    • 2018-02-21
    • 2015-07-06
    相关资源
    最近更新 更多