I'm totally new to Rails and I'm playing with it. Now I'm trying to understand the strong parameter
feature introduced in Rails 4. Below is my code:
class PostsController < ApplicationController
def index
end
def show
end
def create
p = Post.new(create_post_params)
p.save
redirect_to p
end
def new
end
private
def create_post_params
params.require(:post).permit :title, :body
end
end
Beside the controller, I also have a Post model with a title
and a body
. My question is what is this :post thing in params.require(:post).permit :title, :body
? I write it as :post, is it because I'm currently inside the PostsController
? Or I'm reading the properties of a Post
?
Based on gdpelican's answer, if my new.html.erb
is like this:
<h1>Create a post</h1>
<%= form_for :post, url: posts_path do |f| %>
<div class="form-group">
<%= f.label :title %>
<%= f.text_field :title, class: "form-control" %>
<p class="help-block">Please type the title of the post</>
</div>
<div class="form-group">
<%= f.label :body %>
<%= f.text_area :body, class: "form-control", rows: 5 %>
<p class="help-block">Please type the body of the post</>
</div>
<%= f.submit class: "btn btn-primary" %>
<% end %>
It's the :post part in <%= form_for :post, url: posts_path do |f| %>
determines that I should use :post in params.require(:post).permit :title, :body
, right?
Your parameters (typically) look like this
{"utf8"=>"✓", "authenticity_token"=>"...", "post"=>{"title"=>"My title", "body" =>"Body of my Post"}}
When you require a specific key from the parameters (for example post) Rails will throw an error if the hash it was passed doesn't have "post"=>{....}
, then once it passes that check it permits the allowed keys and returns only the parameters nested under "post" hash allowed. To copy the api docs examples
params = ActionController::Parameters.new({
person: {
name: 'Francesco',
age: 22,
role: 'admin'
}
})
params.require(:person).permit(:name, :age)
=>{"name"=>"Francesco", "age"=>22}
So after your strong params check, the return is a hash of :post
parameters that you have allowed.
EDIT: To answer your second question.
That is one way of thinking about it. Your form syntax (form_for :post
) is creating the post
hash with the attributes nested inside, and sending it as part of the overall parameters hash. And your params.require(:post)
is taking the entire params, and finding only the hash key it wants (post
) and then permitting the keys that are inside the post hash.