Visualizzazione di oggetti associati
-
06-07-2019 - |
Domanda
Sono un principiante di Ruby on Rails e avevo una domanda sulla logica di visualizzazione in caso di oggetti associati:
I miei modelli sono simili a
class Post < ActiveRecord::Base
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :post
end
E quello che voglio visualizzare è qualcosa come un elenco di tutti i post e i primi tre commenti per ciascuno.
Quindi, ho mantenuto semplice l'azione dell'indice postcontroller
class PostController < ApplicationController
#..
def index
@posts = Post.find(:all)
end
#..
end
Ora nelle visualizzazioni / posts / index.html.erb
posso fare qualcosa del genere @posts.comments
che posso ripetere per le prime tre voci. Ma come posso accedere alle funzionalità normalmente eseguite nel modello (in questo caso il modello associato) come l'ordinamento, l'ambito ecc. Nella vista (o nel controller)?
Soluzione
Dovresti evitare di scrivere accessi aziendali complessi nella vista. In questo caso, la tua esecuzione è abbastanza semplice da poter scrivere tutto il codice nella tua vista. Dovrebbe apparire così
<% @posts.each do |post| %>
<% @post.comments.all(:limit => 3, :order => "created_at DESC").each do |comment| %>
do something
<% end %>
<% end %>
Ci sono un paio di possibili miglioramenti. Innanzitutto, utilizza un named_scope.
class Post < ActiveRecord::Base
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :post
named_scope :recent, proc { |limit| :limit => limit || 3, :order => "created_at DESC") }
# you can also hard-code the limit value (ScottD)
named_scope :recent, :limit => 3, :order => "created_at DESC"
end
<% @posts.each do |post| %>
<% @post.comments.recent.each do |comment| %>
do something
<% end %>
<% end %>
Se ho ragione, il .each può essere rimosso.
<% @posts.each do |post| %>
<% @post.comments.recent do |comment| %>
do something
<% end %>
<% end %>
Se preferisci, puoi anche definire una relazione personalizzata (questo è per relazioni davvero complesse).
Altri suggerimenti
È possibile utilizzare un metodo find sull'associazione che specifica un limite come:
@post.comments.find(:all, :limit => 3)
dal tuo punto di vista, oppure puoi creare un'altra associazione nel tuo modello di Post qualcosa come:
has_many :first_three_comments, :limit => 3, :class_name => "Comment"
e quindi puoi semplicemente fare riferimento a quell'associazione come
@ post.first_three_comments.each do | comment | ...
Spero che sia d'aiuto.