Rails 4 Strong Parameters Without Required Parameters

Rails 4 strong parameters without required parameters

You can use fetch instead of require.

def device_params
params.fetch(:device, {}).permit(:notification_token)
end

Above will return empty hash when device is not present in params

Documentation here.

Rails: .require() without actually requiring it?

You can use fetch instead of require:

params.fetch(:subscriber).permit(:utm_source, :utm_medium, :utm_campaign, :utm_term, :utm_content)

Check the rails guides for more information on strong parameters.

Rails strong parameters - Request allowed without required key

This behaviour is because of the ParamsWrapper functionality which is enabled by default in Rails 6. wrap_parameters wraps the parameters that are received, into a nested hash. Hence, this allows clients to send requests without nesting data in the root elements.

For example, in a model named Tag, it basically converts

{
name: "Some name",
age: "Some age"
}

to

{
tag:
{
name: "Some name",
age: "Some age"
}
}

However, as you see in your test, if you change the required key to not_tag, the wrapping breaks the API call, as expected.

This configuration can be changed using the config/initializers/wrap_parameters.rb file. In that file, you could set wrap_parameters format: [:json] to wrap_parameters format: [] to disallow such wrapping of parameters.

Allowing only certain values though a strong parameter in Rails 4

delete_if cleans it up. Still a bit hacky, but slightly less so : )

params.require(:company_user).permit(:otp_setup).delete_if do |key, val|
key == 'otp_setup' && val == true
end

This leaves the original params object intact.

There isn't a built in way to do this. It looks like there used to be but no more https://github.com/rails/strong_parameters/issues/167

delete_if is defined on Hash in the core library, so it is probably the best way to do it in Ruby and by extension in Rails in the absence of a built in method.

Update

I thought it was an interesting idea, so I wrote a small gem called allowable for this type of use case. It will add a few methods to Hash and ActionController::Parameters: #allow, #allow!, #forbid and #forbid!

You would use it like this

params.require(:company_user).permit(:otp_setup).forbid(otp_setup: [true])

# or

params.require(:company_user).permit(:otp_setup).allow(otp_setup: [false])

You can specify a single value or an array of values, and it doesn't mutate the original params object

rails 4 using strong parameters with no controller

You permit the parameters into whichever controller you are sending them through. It sounds like you are sending them through your track controller, if so you would add them there.

see this question about how to permit nested params Rails 4 - Strong Parameters - Nested Objects

Shortcut for including strong parameters in Rails 4 : without listing all fields

Strong Parameters were introduced in Rails 4:

It provides an interface for protecting attributes from end-user
assignment. This makes Action Controller parameters forbidden to be
used in Active Model mass assignment until they have been whitelisted.

Basically, it means only certain param values will be sent through your controller to the model (thus allowing you more control over which data is handled by Rails)


DRY

If you're wanting to use strong params for multiple controllers, or just want to DRY up the process, we use this:

#app/controllers/application_controller.rb
private

#Strong Params
def permitted_params
@resource = self.resource_class
@model = "#{@resource}".downcase.to_sym

attributes = @resource.attribute_names + %w(custom items here)
params.permit(@model => attributes)
end

Strong Parameters and Find in Rails 4

So to clear a few things up.

Strong Parameters is responsible for the allowed parameters which are passed to your database. It should prevent the users to modify attributes in the database which they aren't allowed to modify.

For example:

You have the following table with columns:

User:
- firstname
- lastname
- email
- password_digest
- role (user, admin)

You probably want to prevent normal users to change their role. But if you pass a parameters hash as it is to the database, he could also add a role key with value to the hash. Your application would accept it. Strong parameters checks the hash and prevent the change.

In your example above, Strong Parameters brings no advantages. You assign the values directly to the appropriate table columns. It isn't possible to modify any other attributes in the database for the user. If you don't have any other methods in your controller, you could remove the entire #order_params. Strong Parameters just raises an exception if you would try to pass a hash directly through.

However I would recommend you to search for the payment in the database before you assign it. If you assign payment_id directly you have no guarantee that payment exists. So first check for the payment and if you found it assign it to the order.

Here is how I would have done it:

class PaymentConfirmationController < ApplicationController
before_action :authenticate_user!
before_action :authorize_user! # To DRY up your code

def lookup
@orders = Order.where(:status => 'PENDING')
end

def confirm
@order = Order.find(params[:order_id])
@payment = Payment.find(params[:operation_id])
# You should catch the exceptions if an order or payment wasn't found

@order.payment = @payment
@order.payment_confirmation_date = Time.now()
@order.save
end

private

def authorize_user!
authorize! :confirm, :confirmpayment
end
end

I haven't tested the code but it should work.

Here are the Docs of Strong Parameters. They describe everything in more detail.

I hope this helps!

Happy coding :)

Rails4 Strong parameters without database column

Please, permit only the params you expect your user send with data. If start_time is not user data for update your db, use this way:

params.require(:timeslot).permit(:employee_id, :dienstplan_id, :start_date)

Strong parameters prevents save data that user sends and you don't want he/she update.

If you use :start_time, it must be defined at your model.

Ops, I've seen your update:

@e.start_date = @e.start_date.to_s + " " + @e.start_time.to_s

If you send :start_time to an Timeslot instance them start_time must be a method of Timeslot model. Defined by rails if it is a db field, defined with attr_accesor or att_reader or defined by a def key on your source model.

If not @e.start_time trigger undefined method 'start_time'.

edited again:

Now, start_time is a model variable. Make sure it is send to the form in the same way that you do with the fields. By default we use an f <%= f.text_field :the_field %>. Just don't forget the f.

Now you must permit this field again, if you follow my first advice.



Related Topics



Leave a reply



Submit