Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to require multiple strong params in Rails?

I'm trying to do some server-side validation for a form in Rails, and I would like to require specific fields to have a value. Here are the params in my controller:

private
def post_params
  params.require(:post).permit(:title, :text, :slug)
end

The problem is that the server merely permits these params — it doesn't require them, so it's possible to submit a completely blank form.

My understanding is that params.require only accepts one argument, and I've tried getting around this with no success:

private
def post_params
  params.require(:post, :title, :text, :slug)
end
# => wrong number of arguments (4 for 1)

private
def post_params
  all_params = [:post, :title, :text, :slug]
  params.require(all_params)
end
# => param is missing or the value is empty: [:post, :title, :text, :slug]

private
def post_params
  params.require(:post).require(:title).require(:text).require(:slug)
end
# => private method `require' called for "test thing":String

Is there any way to require multiple strong params?

like image 481
Ian Valentine Avatar asked Dec 15 '22 13:12

Ian Valentine


2 Answers

Strong Parameters are used for mass assignment. What does mass assignment means is that when you submit a form multiple values are submitted i.e., multiple attributes of a model so you add them in the params.require(:post).permit. You are seeing the word permit which means this attributes are permitted to be mass assigned. Now suppose you are writing this in controller:

def post_params
  params.require(:post).permit(:title, :text, :slug)
end

and in your params suppose you have:

{"post"=>{"title"=>'Test',"text"=>"Text test","slug"=>"any random name","type"=>"article"}}

Now if you do:

@post = Post.new(post_params)
@post.save

It will give you unpermitted parameters :type because you have not whitelisted the type parameter. This is given for security reasons so that you only allow attributes that needs to be updated by user from the view are permitted. And the strong parameters are introduced from rails 4 onwards.

Now the thing you need to require these parameters that the user fills them so this needs to be done in the model like this:

class Post < ActiveRecord::Base
  validates_presence_of :title, :text, :slug
end

This is a validation which will make the users enter the title, text and slug necessarily. There are more type of validations and some custom validations too which can be written according to the needs.

More Info:

Strong Parameters

Validations

Hope this helps

like image 176
Deepesh Avatar answered Feb 24 '23 14:02

Deepesh


Strong params is not (and cannot) be used for validating the presence of attributes. As @Deep said you use the validate presence for that.

The academic question remains how to require multiple strong params, the word 'params' is misleading here as the 'require' part specifies the key of the attribute hash. The reason require only accepts one is because typically a form is submitted with an attribute hash representing a single object - nesting aside.

In theory though, if your params hash looked contained these key/value pairs:

... this: { name: 'this', number: 1 }, that: { color: 'red', size: 'big'} ...

You might legitimately want to do requires for both this: and that: and permit attributes for them independently, if so you could do this:

def this_and_that_params
  { this: params.require(:this).permit(:name), that: params.require(:that).permit(:color) }
end

which would return:

... this: { name: 'this' }, that: { color: 'red' } ...
like image 31
sgbett Avatar answered Feb 24 '23 15:02

sgbett