Zogimu
Zogimu

Reputation: 211

How can i set the default values of controller parameters?

I have a customers table on my database and a column named as "last_updated_by" . I want to add current users name as a plain text in this field.

I got devise installed on my app so it gives me the current_user parameter.I tried to add current_user.name to the customers_controllers permitted parameters but it did not worked.

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

How can i set some default values in controller.

Upvotes: 8

Views: 12544

Answers (4)

3limin4t0r
3limin4t0r

Reputation: 21130

Since you're asking about setting a default value I suggest using the with_defaults method, which is simply an (more expressive) alias for reverse_merge.

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

reverse_merge does the same thing as merge, the only difference is what happens for conflicting keys. merge uses the value of the hash passed through the parameters, whereas reverse_merge prefers the value of the receiver.

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

Upvotes: 16

Sebastián Palma
Sebastián Palma

Reputation: 33420

If you need the last_updated_by param to go within the customer_params (customer hash key for ActionController::Parameters), then:

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

The before_action callback adds the new key last_updated_by on the customer params only before the create action is executed.

Notice, no need to modify the customer_params to permit it.


As showed by @JohanWentholt, with_defaults seems to be the best way. Go for it.

Waiting the OP chooses the correct answer.

Upvotes: 1

Ashok Damaniya
Ashok Damaniya

Reputation: 303

As method params.permit method is used to filter the parameter you want to create the object with, you can use any of the solution given above, but if you want to modify params in def customer_params then i would like to modify your 2nd solution

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

Upvotes: 1

Lucas Andrade
Lucas Andrade

Reputation: 4580

If you need a default value only if params[:last_updated_by] is not present in the body of your request, you can try:

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

Now if you need to set a default value on every create and update if last_updated_by is nil, you should do this on Customer model:

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

Upvotes: 2

Related Questions