Permalink
Browse files

Getting Started Guide: strong_parameters

Stuff didn't work because of strong_parameters. Now the right calls are
in place.
  • Loading branch information...
1 parent a1748f3 commit aadd16f913da8b93ac1d35bb2c74b18d73b47712 @steveklabnik steveklabnik committed Jan 22, 2013
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -583,9 +583,31 @@ content:
</p>
```
-Finally, if you now go to
-<http://localhost:3000/posts/new> you'll
-be able to create a post. Try it!
+If you now go to
+<http://localhost:3000/posts/new> you'll *almost* be able to create a post. Try
+it! You should get an error that looks like this:
+
+![Forbidden attributes for new post](images/getting_started/forbidden_attributes_for_new_post.png)
+
+Rails has several security features that help you write secure applications,
+and you're running into one of them now. This one is called
+'strong_parameters,' which requires us to tell Rails exactly which parameters
+we want to accept in our controllers. In this case, we want to allow the
+'title' and 'text' parameters, so change your `create` controller action to
+look like this:
+
+```
+ def create
+ @post = Post.new(params[:post].permit(:title, :text))
+
+ @post.save
+ redirect_to action: :show, id: @post.id
+ end
+```
+
+See the `permit`? It allows us to accept both `title` and `text` in this
+action. With this change, you should finally be able to create new `Post`s.
+Visit <http://localhost:3000/posts/new> and give it a try!
![Show action for posts](images/getting_started/show_action_for_posts.png)
@@ -729,7 +751,7 @@ def new
end
def create
- @post = Post.new(params[:post])
+ @post = Post.new(params[:post].permit(:title, :text))
if @post.save
redirect_to action: :show, id: @post.id
@@ -864,8 +886,8 @@ method: :patch do |f| %>
This time we point the form to the `update` action, which is not defined yet
but will be very soon.
-The `method: :patch` option tells Rails that we want this form to be
-submitted via the `PUT` HTTP method which is the HTTP method you're expected to use to
+The `method: :patch` option tells Rails that we want this form to be submitted
+via the `PATCH` HTTP method which is the HTTP method you're expected to use to
**update** resources according to the REST protocol.
TIP: By default forms built with the _form_for_ helper are sent via `POST`.
@@ -883,7 +905,7 @@ And then create the `update` action in `app/controllers/posts_controller.rb`:
def update
@post = Post.find(params[:id])
- if @post.update(params[:post])
+ if @post.update(params[:post].permit(:title, :text))
@frodsan

frodsan Jan 22, 2013

Contributor

Shouldn't we encourage permissible parameters encapsulation? e.g:

    if @post.update(post_params)
    ...

    private

      def post_params
        params[:post].permit(:title, :text)
      end
@guilleiguaran

guilleiguaran Jan 22, 2013

Owner

๐Ÿ‘ ๐Ÿ˜„

@steveklabnik

steveklabnik Jan 22, 2013

Member

This is a Getting Started Guide. Just covering the very absolute basics, I didn't want to delve into extra complex things.

@fxn might feel differently. :)

@frodsan

frodsan Jan 22, 2013

Contributor

And WDYT about adding the "set shared record pattern" 339e4e8?

@steveklabnik

steveklabnik Jan 22, 2013

Member

Same thing: this guide isn't meant to teach you everything about Rails, it's meant to give you a taste of what Rails is like.

I've been giving some thought to a three-part "build a simple Rails app" that would demonstrate actually doing this, with all the actual good stuff. But I think it detracts from Getting Started.

@fxn

fxn Jan 22, 2013

Owner

These examples in the guide are kind of scattered, you'd need to introduce the helper and reuse it in a couple of places... the current compromise is fine for me.

redirect_to action: :show, id: @post.id
else
render 'edit'
@@ -1388,7 +1410,7 @@ Let's wire up the `create` in `app/controllers/comments_controller.rb`:
class CommentsController < ApplicationController
def create
@post = Post.find(params[:post_id])
- @comment = @post.comments.create(params[:comment])
+ @comment = @post.comments.create(params[:comment].permit(:commenter, :body))
redirect_to post_path(@post)
end
end
@@ -1559,6 +1581,9 @@ Then you make the `app/views/posts/show.html.erb` look like the following:
<%= @post.text %>
</p>
+<h2>Comments</h2>
+<%= render @post.comments %>
+
<h2>Add a comment:</h2>
<%= render "comments/form" %>

0 comments on commit aadd16f

Please sign in to comment.