Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails different params in create and update

I have an Event model. And it has budget param. Business logic requires that budget, once set on creation, cannot be changed later. On client side this means that I disable corresponding field.

But of course, this data can still be sent to server manually. On server, prior setup was the following:

def event_params
  params
    .require(:event)
    .permit(
      :title,
      :budget,
      ...
    )

And event_params were used in both create and update methods. I was considering creating two distinct sets of permitted params for create and update, but I don't like this idea because DRY.

What would your suggestions on this question would be? How to prevent budget updating while keeping code elegant?

like image 605
borisano Avatar asked Oct 23 '25 07:10

borisano


2 Answers

As you've suggested, you could use two separate helpers event_params_for_create and event_params_for_update.

In order to DRY them up, you could try this:

def event_params_common
  [:generic_value_1, :generic_value_2]
end

def event_params_for_create
  event_params_preprocessed
    .require(:event)
    .permit(event_params_common.concat([:extra_create_only_param]))
end

def event_params_for_update
  event_params_preprocessed
    .require(:event)
    .permit(event_params_common)
end

You would then use the respective methods during create or update, for instance;

# def create
@event = Event.new(event_params_for_create)

# def update
@event.update(event_params_for_update)

In this way, you're only configuring your common fields once.

like image 175
Ollie Bennett Avatar answered Oct 24 '25 22:10

Ollie Bennett


If the budget can't be changed later, you can't allow the :budget on the params of an update action (eg: @event.update(event_params)). This is not a violation of DRY, it's a security matter of your site.

As an example, check how devise works. He has one set of parameters for sign_up and a different one for account_update https://github.com/plataformatec/devise/blob/master/app/controllers/devise/registrations_controller.rb#L137

But if you want to use the same parameters for both create and update, you can move the business logic to a service. Here is a nice article about them: https://blog.engineyard.com/2014/keeping-your-rails-controllers-dry-with-services

The idea is create an EventService with one method to create and other to update. Each method treats the allowed parameters received from your controller (from event_params)

like image 40
Victor Avatar answered Oct 24 '25 21:10

Victor



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!