6

Ok ... Soy nuevo en Rails, y sé que esto se ha preguntado antes, pero todavía estoy confundido sobre cómo abordar el siguiente problema común. Puedo hacer que la asociación funcione, pero tener algo que funcione mágicamente y empezar a usar malos hábitos no es algo que quiera hacer.Creación de asociaciones de modelos de rieles para has_many y belongs_to

Di que estoy compilando un blog. Tengo dos recursos: artículos y usuarios. Cada usuario tiene muchos artículos, y cada artículo pertenece a un usuario:

rails g scaffold User name:string email:string 
rails g scaffold Article user_id:integer title:string content:string 

Modelo de Usuario:

class User < ActiveRecord::Base 
    has_many :articles 
end 

Artículo Modelo:

class Article < ActiveRecord::Base 
    belongs_to :user 
end 

Ahora, en mi índice de artículos, que pueda haga algo como:

…table headers... 
<% @articles.each do |article| %> 
    <tr> 
    <td><%= article.user.name %></td> 
    <td><%= article.title %></td> 
    <td><%= article.desc %></td> 
    <td><%= article.content %></td> 
    <td><%= link_to 'Show', article %></td> 
    <td><%= link_to 'Edit', edit_article_path(article) %></td> 
    <td><%= link_to 'Destroy', article, confirm: 'Are you sure?', method: :delete %></td> 
    </tr> 
<% end %> 
</table> 

Y todo lo que necesito para esa asociación de modelos para el Nombre de usuario es poner "@articles = Article.all" en la acción del índice antes de responder_to. ¡Muy genial!

¿Qué sucede si quiero enumerar todos estos artículos (me estoy saltando la búsqueda aquí por simplicidad) en mi página de inicio, usando la acción de índice en mi controlador de inicio?

Sé que puedo hacer algo como esto en el controlador principal:

class HomeController < ApplicationController 
    def index 
    @articles = Article.joins(:user) 
    end 
end 

... y luego puedo acceder a estos datos en mi vista casa-> índice:

<div class="row"> 
    <% @articles.each do |article| %> 
    <div> 
     <h3><%= link_to article.title, 
     :controller => "articles", :action => "show", :id => article.id %></h3> 
     <small>Posted on <%= article.created_at %> by 
     <a href="#"><%= article.user.name %></a></small> 
    </div> 
    <% end %> 
</div> 

Primera pregunta : Al acceder a los datos del usuario para todos los artículos, ¿debería utilizar un: une o an: includes? Parece que ambos funcionan, pero me pregunto cuál es el correcto en esta situación, y cuál generalmente funciona más rápido.

@articles = Article.joins(:user) 

web frente a

@articles = Article.includes(:user) 

Segunda pregunta: En mi andamio para el artículo (la construcción de la migración), debería usar user_id: número entero o usuario: referencias. ¿Hacen lo mismo o prefieren uno sobre el otro? Si utilizo: integer como tipo de campo, ¿se recomienda que también agregue un índice para él (add_index: articles,: user_id)? Encontré un gran RailsCast, y hace un gran trabajo de explicación, pero me pregunto si alguien más tiene otra opinión.

Si ayuda, estoy en Rails 3.2.2.

Gracias!

Respuesta

3

Primera pregunta:

Quiere llamar a todos los artículos con los datos de sus usuarios de una manera eficiente, debe utilizar

@articles = Article.includes(:user) 

Obtendrá la lista de todos los artículos en su base de datos, cada artículo con su usuario ya recuperado

Con @articles = Article.joins(:user) obtendrá solo los artículos que tienen un usuario, y cuando haga article.user en cualquiera de estos artículos, generará una nueva solicitud SQL.

Para obtener más información: http://guides.rubyonrails.org/active_record_querying.html (si aún no ha leído este conjunto de guías, le recomiendo encarecidamente que lo haga ahora).

Segunda pregunta:

que utilice el formulario user_id:integer. No estoy seguro de que user:references se pueda usar en la línea de comando rails g scaffold. Un índice en la columna 'articles.user_id' mejorará la velocidad de recuperación cuando se buscan artículos de un usuario específico. Agregue este índice solo si su aplicación hará este tipo de búsqueda.

+0

Gracias por la aclaración. De los registros, puedo ver la consulta pasada a mi base de datos, pero no estaba seguro de cómo trata Rails 'incluye' frente a 'une'. ¡La respuesta 'índice' también es muy útil! – JohnnyCoder

5
  1. Debe utilizar @articles = Article.all :include => :user para recuperar sus registros. Lea Rails :include vs. :joins para obtener más información sobre por qué esto generalmente es más rápido que :joins. (Básicamente, le da la misma información sin duplicados).)

  2. Rails tiene un atajo para las asociaciones belongs_to cuando se trata de migraciones. Use belongs_to :user y Rails incluirá automáticamente la columna user_id (del tipo integer) por usted.

Ejemplo:

class CreateArticle < ActiveRecord::Migration 
    def self.up 
    create_table :articles do |t| 
     t.belongs_to :user # Creates 'user_id' column 
     t.timestamps 
    end 
    end 
end 
+0

Gracias! No sabía sobre la taquigrafía 'pertenece a' para las migraciones, definitivamente tendré que agregar eso a mi arsenal. – JohnnyCoder

Cuestiones relacionadas