'How to remove a field from params[:something]
My registration form, which is a form for the Users model, takes a string value for company. However, I have just made a change such that users belongs_to companies. Therefore, I need to pass an object of Company to the Users model.
I want to use the string value from the form to obtain the an object of Company:
@user.company = Company.find_by_name(params[:company])
I believe the above works, however the form is passing the :company (which is string) into the model when I call:
@user = User.new(params[:user])
Therefore, I want to know (and cannot find how) to remove the :company param before passing it to the User model.
Solution 1:[1]
Rails 4/5 - edited answer (see comments)
Since this question was written newer versions of Rails have added the extract! and except eg:
new_params = params.except[the one I wish to remove]
This is a safer way to 'grab' all the params you need into a copy WITHOUT destroying the original passed in params (which is NOT a good thing to do as it will make debugging and maintenance of your code very hard over time).
Or you could just pass directly without copying eg:
@person.update(params[:person].except(:admin))
The extract!
(has the ! bang operator) will modify the original so use with more care!
Original Answer
You can remove a key/value pair from a Hash using Hash#delete
:
params.delete :company
If it's contained in params[:user], then you'd use this:
params[:user].delete :company
Solution 2:[2]
You should probably be using hash.except
class MyController < ApplicationController
def explore_session_params
params[:explore_session].except(:account_id, :creator)
end
end
It accomplishes 2 things: allows you to exclude more than 1 key at a time, and doesn't modify the original hash.
Solution 3:[3]
The correct way to achieve this is using 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
This way you have more control over which params should be passed to model
Solution 4:[4]
respond_to do |format|
if params[:company].present?
format.html { redirect_to(:controller => :shopping, :action => :index) }
else
format.html
end
end
this will remove params from the url
Solution 5:[5]
To be possible to delete you can do a memo:
def parameters
@parameters ||= params.require(:root).permit(:foo, :bar)
end
Now you can do:
parameteres.delete(:bar)
parameters
=> <ActionController::Parameters {"foo" => "foo"} permitted: true>
Solution 6:[6]
Rails 5+: Use the handy extract!
method with strong params!
The extract!
method removes the desired variable from the Parameters object (docs) and returns a new ActionController::Parameters object. This allows you to handle params properly (i.e. with strong params) and deal with the extracted variable separately.
Example:
# 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))
Full example in controller
Of course, we could wrap this up in a handy method in our controller:
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
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | rmcsharry |
Solution 2 | samuraisam |
Solution 3 | Deepak Mahakale |
Solution 4 | Jan Klimo |
Solution 5 | Washington Botelho |
Solution 6 | Matt |