【问题标题】:Rails - ActionController::Parameters include controller value with form valuesRails - ActionController::Parameters 包括控制器值和表单值
【发布时间】:2014-10-23 23:10:03
【问题描述】:

我有一个会话变量 (user_id),我想将它作为外键包含在用户插入的记录中。我将表单值全部通过表单提交到我的控制器的 entity.update(params) 方法,使用默认参数定义没有问题。该代码看起来像

 def brand_params
    @brand_params = params.require(:brand).permit(:name, :brand_type, :profile_id)
  end

更新方法是这样的

if @brand.update(brand_params)
        format.html { redirect_to @brand, notice: 'Widget was successfully updated.' }
        format.json { render :show, status: :ok, location: @brand }
      else
        format.html { render :edit }
        format.json { render json: @brand.errors, status: :unprocessable_entity }
      end

现在我想将 :profile_id 会话变量附加到 @brand_params 并在此处跟随其他线程,我尝试了一个 setter 方法:

def set_brand_params(key, val)
    if @brand_params != nil
      @brand_params[key] = val
    end
  end

但是,调用它时,@brand_params 始终为零。尝试直接添加到 brand_params 哈希是行不通的,因为它是一种更好的方法。如果有更好的方法来满足这个(我假设是常见的)用例,我全神贯注!否则,我想知道为什么 var 始终为零,尽管在这种情况下,至少 brand_params 方法将其视为已定义且具有价值。我在Adding a value to ActionController::Parameters on the server side得到了这个解决方案

这里是按要求更新的方法:

def update
    puts "update"
    set_brand_params("profile_id", session[:prof])
    respond_to do |format|
      if @brand.update(brand_params)
        format.html { redirect_to @brand, notice: 'Widget was successfully updated.' }
        format.json { render :show, status: :ok, location: @brand }
      else
        format.html { render :edit }
        format.json { render json: @brand.errors, status: :unprocessable_entity }
      end
    end
  end

【问题讨论】:

  • 如果您在调用brand_params 之前使用set_brand_parmas,是的,@brand_params 未定义(无)。
  • 是的,如果我将@brand_params 变量移动到构造函数(这里是new())它不是零,所以这就是答案!我仍然不清楚最佳实践,因为现在这个受保护的变量是公开的......但已经足够了。
  • 拜托,你能编辑问题并添加整个方法更新吗?

标签: ruby-on-rails parameters actioncontroller


【解决方案1】:

我不同意将您的数据与参数合并。因为您必须只允许您希望用户更新的字段。在这种情况下,您不希望用户在品牌上更新 profile_id,这是一种安全最佳做法。

那么brand_params必须是:

def brand_params
  @brand_params = params.require(:brand).permit(:name, :brand_type)
end

您的方法更新可能如下所示:

def update
  @brand = Brand.find(params[:id])
  @brand.assign_attributes(profile_id: session[:prof])
  respond_to do |format|
    if @barnd.update(brand_params)
      format.html { redirect_to @brand, notice: 'Widget was successfully updated.'}
      format.json { render :show, status: :ok, location: @brand }
    else
      format.html { render :edit }
      format.json { render json: @brand.errors, status: :unprocessable_entity }
    end
  end
end

你根本不需要set_brand_params这个方法。

如果这不起作用,请发布入口控制器,我希望我们能找到问题。

编辑:添加 respond_to。

【讨论】:

  • 在我看到你的代码之后,我假设你的控制器上有一个 before_filter 或 before_action,它设置了 @brand 变量,就像我在更新方法开始时所做的那样。在这种情况下,将 set_brand_params 方法替换为 @brand.assign_attributes(profile_id: session[:prof])
  • 是的,@Alejandro,这行得通。通过使用 assign_attributes 并从参数中删除,这更加安全。谢谢!
猜你喜欢
  • 2021-03-02
  • 1970-01-01
  • 1970-01-01
  • 2023-04-11
  • 1970-01-01
  • 2019-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多