user4571629
user4571629

Reputation: 450

rails show each category content

This is how my CategoriesController looks like:

class CategoriesController < ApplicationController

  def index     
    @categories = Category.all
  end

  def show
    @category = Category.find(params[:id])          
  end   

end

inside my show.html.erb I wrote this to display the category name:

<h2><%= @category.name %></h2>

I also have a PagesController which I made relations with the Category
I have few Pages assigned to Category (for example category_id: 1)
When I click on the category link from my homepage:

<%= link_to "category", category_path(cat) %>

It goes to the show page which is great

How can I display on the show.html.erb all the Pages that belongs to this category that I've clicked on?

Upvotes: 1

Views: 407

Answers (3)

RAJ
RAJ

Reputation: 9747

You should use includes for enhanced performance of your application. It will return all expected records from pages also and that's without firing database query again. @category.pages in ERB will not make database query. Hence, you will have efficient code.

In your show action:

def show
  @category = Category.find(params[:id]).includes(:pages)
end

In show.html.erb:

<%= "Category: #{@category.name}" %>
<h1> POSTS </h1>
<table>
  <tr>
    <% @category.pages.each do |page| %>
      <td> <%= page.field1 %> </td>
      <td> <%= page.field2 %> </td>
    <% end %>
  </tr>
</table>

Rich Peck edit

Normally, ActiveRecord does something called lazy loading, which means that it will only execute a DB query when it needs to. This is normally highly efficient; unfortunately causes a problem when you call associative data.

When calling @category.pages, you get the n+1 issue, which means that each time you call the Category.find query, an extra query will be used to load the pages:

The above code will execute just 2 queries, as opposed to 11 queries in the previous case:

SELECT * FROM clients LIMIT 10
SELECT addresses.* FROM addresses
  WHERE (addresses.client_id IN (1,2,3,4,5,6,7,8,9,10))

So using .includes essentially appends all the pages to your @category, making it much more efficient than letting it load lazily.

Upvotes: 2

Sravan
Sravan

Reputation: 18647

You should call the pages assosication with the category model as,

<%= @category.name %>
<h1> PAGES </h1>
<table>
  <tr>
    <% @category.pages.each do |page| %>
      <td> <%= page.title %> </td>
      <td> <%= page.content %> </td>
   <% end %>
  </tr>
</table>

This will do for you.

Upvotes: 2

Harry Bomrah
Harry Bomrah

Reputation: 1668

Well mostly it depends on how you made your relationships between category and page. With what i can see from your code, you can do something like this.

@pages = Page.where(:category_id => 1)

Update

As per to your relationships

@pages = @category.pages

Upvotes: 0

Related Questions