4

I have a post object with a boolean called :published. The the definition for index in the controller looks like this:

def index
  @posts = Post.all

  respond_to do |format|
    format.html # index.html.erb
    format.json { render json: @posts }
  end
end

And this links to that page:

<%= link_to 'All posts', posts_path %>

Let's say instead I want the option of showing only posts where post.published? is true.

  • Should I have a separate method in the controller to handle the case where only :published posts would be shown?
  • Can I alter the index method to handle a parameter being passed to it?
  • What would the link_to look like?

2 Answers 2

3

In theory, for filtering results by keywords / categories, it is fine to display the logic in the same controller via a param. I would have it as:

<%= link_to 'All posts', posts_path(:published => true) %>

Then in your controller / index action:

def index
  @posts = Post.all
  @posts = @posts.where(:published => true) if params[:published].present?
  ...

To refactor your code, I would scope the method in the model, with something like:

scope :published, where(:published => true)

Then in your controller you can just have:

@posts = @posts.published if params[:published].present?

For more information on chaining / model scopes: http://guides.rubyonrails.org/active_record_querying.html#scopes

Sign up to request clarification or add additional context in comments.

6 Comments

Thank you for the response. It doesn't give me an error, but it still lists all the posts, not just the published ones.
You might want to do some debugging on your end. Is the code executing if a param is passed? Are there any @posts where published is true? In Rails console, run Post.where(:published => true). Does that return anything?
Post.where(:published => true) works in console. There are some posts where published is true. I'm not sure how to test if the code is executing. I think that the param may not be getting passed.
changed to the link to: <%= link_to 'Published Posts', posts_path(:published => :true) %> and that seemed to pass the paramater
Made the necessary edits on my post. Glad its now working for you
|
2

To keep it really simple (no scopes), just do the following

def index
  @posts = if params[:published].present?
    Post.where(:published => true)
  else
    Post.all
  end
...

And then to add the link with params do

%= link_to 'Published Posts', posts_path(:published => true) %>

1 Comment

Thing is if you do it this way, you need to specify a value for the parameter, otherwise Rails discards it. And this is pretty confusing: link_to 'Published Posts', posts_path(:published => false) => will still include published posts

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.