Mike Cuddy Mike Cuddy - 5 months ago 11
Ruby Question

two models in rails and how to bring them together

I am working on a simple project with Rails 4. I have two models right now-Author and Books. I currently have it so that the models look like this:

class Author < ActiveRecord::Base
has_many :books
end

class Book < ActiveRecord::Base
belongs_to :author
end


author controller looks like this:

class AuthorsController < ApplicationController

def index
@authors = Author.all
@book = Book.find(params[:author_id])
(Not sure if the @book line is right)
end


My schema looks like this:

create_table "authors", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end

create_table "books", force: :cascade do |t|
t.string "title"
t.string "genre"
t.string "description"
t.integer "author_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end


I have it so that my books index.html.erb I can see the author who wrote the book. For example: <%= book.author.name %>. That works just as I want it to. Now what I want to do, on my author index.html.erb page, is show all of the books that belong to an author.

On the author's index.html.erb page I have the following:

<h1>All Authors</h1>
<p><%= link_to "New", new_author_path, class: "btn btn-primary" %></p>

<div class="container">
<div class="row">
<% @authors.each do |author| %>
<h1><%= author.name %></h1>
<p><%= author.book.title %></p>
<%= link_to "Show", author_path(author), class: "btn btn-primary" %>
<%= link_to "Edit", edit_author_path(author), class: "btn btn-warning"
%>
<%= link_to "Delete", author_path(author), method: :delete, data: {
confirm: "Are you Sure?" }, class: "btn btn-danger" %>
<% end %>
</div>
</div>


The main line that I need help with, I believe, is the following:
<%= author.book.title %> Again, my main question is how do I get it so that on my authors index page I see all of the books that they wrote? Is nesting my routes, like this:

resources :posts do
resources :comments
end


Or is there another way? Thank you for any help and please let me know if you need more information.

Answer

I believe you would loop through the books as such:

<h1>All Authors</h1>
<p><%= link_to "New", new_author_path, class: "btn btn-primary" %></p>

<div class="container">
  <div class="row">
    <% @authors.each do |author| %>
      <h1><%= author.name %></h1>
      <% author.books.each do |book| %>
        <p><%= book.title %></p>
      <% end %>
      <%= link_to "Show", author_path(author), class: "btn btn-primary" %>
      <%= link_to "Edit", edit_author_path(author), class: "btn btn-warning"    
      %>
      <%= link_to "Delete", author_path(author), method: :delete, data: {   
      confirm: "Are you Sure?" }, class: "btn btn-danger" %>
   <% end %>
  </div>
 </div>

The above would work, but it's not efficient as it would result in a (N+1) query.

A way to work around this is:

In your controller,

def index
  @authors = Author.includes(:books)
end

This would still slow down your database, but adding a limit and paginating may help to fix that.