Ask LSBot

Strong Parameters

Our new Active Record models behave mostly the same as before, but with a couple of exceptions.

Handling params

One glaring issue is that if we try to create a post right now, we get this:

ActiveModel::ForbiddenAttributesError in PostsController#create

This is because Active Record models distrust params by default. There are security reasons for this, but we obviously want to allow some params to be used, so we'll have to specify which ones to permit in our post controller:

### app/controllers/posts_controller.rb ###

class PostsController < ApplicationController

  # ...

  def create
    @post = Post.new(post_params)

    # ...
  end

  def update
    if @post.update_attributes(post_params)
      # ...
    end
  end

private

  # ...

  def post_params
    params.require(:post).permit(:title, :body, :author)
  end
end

Here we just create a post_params private helper method and use it to grab the params we want. We then use it in the calls to our Post model in the create and update actions.

The params.require(:post) call makes sure that there is something at params[:post]. Subsequently, .permit(...) grabs the pairs out of that params[:post] hash that we want and allows them to be passed to Post.

A similar params method will be needed in the comments controller. Be sure to add that in as well so that your app works as intended. Additionally, you will need to change your create action for comments_controller.rb

def create
  @comment = @post.comments.build(comment_params)
  if @comment.save
    # ...
  else
    @post.reload.comments
    # ...
  end
end

When comment validation fails, even though the comment is not saved in the database, it is still being associated with the current post in memory. This will raise an exception when rendering the show.html.erb because of its dependency on comment.id where our invalid comment will have an id of nil. Because of the way we wrote our code, we are grabbing all the comments associated with the current post in memory rather than directly from the database. To solve this, we need to add @post.reload.comments during comment validation failures to make sure our current post is synced with the database.

More Resources

For more on these topics, check out:

This conversation with LSBot is temporary. Sign up for free to save your conversations with LSBot.

Hi! I'm LSBot. I'm here to help you understand this chapter content with fast, focused answers.

Ask me about concepts, examples, or anything you'd like clarified from this chapter. I can explain complex topics, provide examples, or help connect ideas.

Want to know more? Refer to the LSBot User Guide.

This conversation with LSBot is temporary. Sign up for free to save your conversations with LSBot.

Hi! I'm LSBot. I'm here to help you think through this exercise by providing hints and guidance, without giving away the solution.

You can ask me about your approach, request clarification on the problem, or seek help when you feel stuck.

Want to know more? Refer to the LSBot User Guide.