【问题标题】:How can i set the default values of controller parameters?如何设置控制器参数的默认值?
【发布时间】:2019-05-23 01:19:24
【问题描述】:

我的数据库中有一个客户表和一个名为 "last_updated_by" 的列。我想在此字段中以纯文本形式添加当前用户名。

我在我的应用程序上安装了设计,因此它为我提供了 current_user 参数。我尝试将 current_user.name 添加到 customers_controllers 允许的参数中,但没有成功。

1-
def customer_params
params.require(:customer).permit(:name, :last_updated_by=>current_user.name)
end

2-
def customer_params
  params[:last_updated_by] = current_user.name
  params.require(:customer).permit(:name, :last_updated_by)
end

3-
def customer_params
  last_updated_by = current_user.name
  params.require(:customer).permit(:name, :last_updated_by=>current_user.name)
end

如何在控制器中设置一些默认值。

【问题讨论】:

  • 你应该解释一下为什么你需要在你的控制器中设置一个默认值,因为将默认值设置为带有 rails 的参数的最佳/简单方法是在模型上
  • 我在主帖中解释过。我想自动添加 last_updated_by 信息。

标签: ruby-on-rails ruby strong-parameters


【解决方案1】:

由于您要设置默认值,我建议使用with_defaults 方法,它只是reverse_merge 的(更具表现力的)别名。

def customer_params
  params
    .require(:customer)
    .permit(:name, :last_updated_by)
    .with_defaults(last_updated_by: current_user.name)
end

reverse_mergemerge 做同样的事情,唯一的区别是冲突键会发生什么。 merge 使用通过参数传递的哈希值,而reverse_merge 更喜欢接收者的值。

h1 = { a: 1, b: 2 }
h2 = { a: 4, c: 5 }
h1.merge(h2)         #=> { a: 4, b: 2, c: 5 }
h1.reverse_merge(h2) #=> { a: 1, b: 2, c: 5 }
# aka ^ with_defaults

【讨论】:

    【解决方案2】:

    如果您需要 last_updated_by 参数进入 customer_params(ActionController::Parameters 的客户哈希键),那么:

    before_action :set_last_updated_by_param, only: :create
    
    private
    
    def set_last_updated_by_param
      params[:customer][:last_updated_by] = params.dig(:customer, :name)
    end
    

    before_action 回调仅在执行创建操作之前在 customer 参数上添加新键 last_updated_by

    注意,无需修改 customer_params 即可。


    正如@JohanWentholt 所示,with_defaults 似乎是最好的方法。去吧。

    等待 OP 选择正确答案。

    【讨论】:

    • 请记住,这不会设置默认值。如果参数中已经存在一个值,则将其覆盖。请改用||= 赋值运算符。
    • 感谢您的回答,但我收到错误“未定义的方法 `name' for :current_user:Symbol”。
    • 好的,我将 params[:customer][:last_updated_by] = params.dig(:customer, :name) 更改为 params[:customer][:last_updated_by] = current_user.name 并且它起作用了。但是我还是很好奇为什么我不能直接在 allowed_pa​​rams 中定义它。
    • 答案仍然没有以这种方式设置默认值。如果您提供 ?customer[last_updated_by]=Some+Name 参数,它将被 set_last_updated_by_param 方法覆盖。使用 permit 时没有设置默认值的原因仅仅是因为 permit 方法不允许您设置默认值。
    • @JohanWentholt 可以通过.with_defaults设置允许参数的默认值
    【解决方案3】:

    如果您仅在请求正文中不存在params[:last_updated_by] 时才需要默认值,您可以尝试:

    def create
      params[:last_updated_by] = params[:last_updated_by].blank? ? 'Default value' : params[:last_updated_by]
      Customer.new(params)
      # finish your controller method
    end
    
    def customer_params
      params.require(:customer).permit(:name, :last_updated_by)
    end
    

    如果last_updated_by 为 nil,现在您需要在每次创建和更新时设置默认值,您应该在 Customer 模型上执行此操作:

    after_save :set_last_updated_by
    
    def set_last_updated_by
      self.last_updated_by = self.last_updated_by.blank? ? 'Default value' : self.last_updated_by
    end
    

    【讨论】:

    • params[:last_updated_by] = params[:last_updated_by].blank? ? 'Default value' : params[:last_updated_by] 可以写成params[:last_updated_by] ||= 'Default value' 两个版本都没有问题,只是提供一个替代方案。
    【解决方案4】:

    由于方法 params.permit 方法用于过滤您要创建对象的参数,您可以使用上面给出的任何解决方案,但是如果您想修改 def customer_params 中的参数,那么我想修改您的第二种解决方案

    def customer_params
      params[:customer][:last_updated_by] = current_user.name 
      params.require(:customer).permit(:name, :last_updated_by)
    end
    

    【讨论】:

      猜你喜欢
      • 2014-10-29
      • 1970-01-01
      • 1970-01-01
      • 2010-11-05
      • 1970-01-01
      • 2018-07-21
      • 2013-01-02
      • 2013-06-01
      • 1970-01-01
      相关资源
      最近更新 更多