如何从 params [ : something ]中删除字段

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

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

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

我相信上面的方法是可行的,但是当我调用:

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

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

109160 次浏览

Rails 4/5-编辑答案 (见评论)

由于这个问题是写的 Rails 的新版本已经添加了 撤退!除了例如:

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

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

或者你可以直接传过去,不用抄。例如:

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

extract!(有! bang 操作符)将修改原来的,所以使用时要更加小心!

原始答案

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

params.delete :company

如果它包含在 params [ : user ]中,那么应该使用:

params[:user].delete :company
respond_to do |format|
if params[:company].present?
format.html { redirect_to(:controller => :shopping, :action => :index) }
else
format.html
end
end

这将从 url 中删除 params

你应该使用 hash 除了

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

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

实现这一点的正确方法是使用 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

通过这种方式,您可以更好地控制哪些参数应该传递给 model

为了能够删除你可以做一个 备忘录:

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

现在你可以做:

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

Rails 5 + : 使用带有强参数的方便的 extract!方法!

extract!方法将所需的变量从 Parameter 对象(医生)中删除,并返回一个新的 ActionController: : Parameter 对象。这允许您正确地处理参数(例如,使用强参数)并分别处理提取的变量。

例如:

# Request { user: { company: 'a', name: 'b', age: 100 } }


# this line removes company from params
company = params.require(:user).extract!(:company)


# note: the value of the new variable `company` is { company: 'a' }
# since extract! returns an instance of ActionController::Parameters


# we permit :name and :age, and receive no errors or warnings since
# company has been removed from params
params.require(:user).permit(:name, :age)


# if desired, we could use the extracted variable as the question indicates
@company = Company.find_by_name(company.require(:company))

控制器中的完整示例

当然,我们可以在我们的控制器中用一种方便的方法来包装它:

class UsersController < ApplicationController
before_action :set_user, only: [:create]


def create
# ...
@user.save
end


def set_user
company = params.require(:user).extract!(:company)
@user = User.new(params.require(:user).permit(:name, :age))
@user.company = Company.find_by_name(company.require(:company))
end
end