2012-11-14 29 views
6

Ho questo modello chiamato Post, idaelly mi piacerebbe usare solo un layout parziale + ONE per ottenere quanto segue.Rails rendering collection in ul li

durante il rendering un unico oggetto, uscite:

%div= post.body 

e quando il rendering di una collezione, uscite:

%ul 
    %li= post.body 
    %li= post.body 
    %li= post.body 

Attualmente ho un messaggi parziali/post.haml cercando come: %li= post.body

e ogni volta che eseguo il rendering di una raccolta, vorrei fare %ul=render @posts

I problemi essendo:

  1. ogniqualvolta il rendering una collezione, devo mettere il rendering in% ul
  2. Il parziale non è utilizzabile per singolo oggetto senza% ul

Sebbene nel 90% dei casi di utilizzo che sto rendendo una raccolta di post, non ha senso che un post parziale non sia utilizzabile come modello stand-alone.


ho pensato che avrei potuto fare qualcosa di simile

# view 
render partial: 'post', collection: @posts, layout: 'list_of_posts' 

# list_of_posts 
%ul= yield 

# posts/post 
%li= post.body 

questo risolverebbe il mio primo problema se funziona, ma non è così. Apparentemente render_collection non accetta l'opzione di layout, quindi è praticamente un punto morto da ciò che posso trovare sulla raccolta di rendering. (Spacer_template potrebbe potenzialmente funzionare, ma

  1. </li><li> come distanziatore è in alcun modo un buon pezzo di codice ..
  2. Haml non permetterebbe questo)

Per quanto riguarda la mia seconda problema, una via d'uscita facile sarebbe rendere tutto in div, ma sono davvero riluttante a farlo quando le cose dovrebbero essere in una lista. Ma per il gusto di farlo funzionare, è probabilmente l'unica soluzione clean-ish. div.list-of-posts > div.post invece di ul.posts > li


so che posso sempre fare qualcosa di simile

# view - collection 
%ul= render @posts, in_list: true 

# view - object 
= render @post 

# posts/post.haml 
- post_counter ||= false 
- tag = post_counter ? :li : :div 
= content_tag tag do 
    = post.body 

ma in questo caso ho ancora bisogno di mettere un ul% ogni volta che viene passata una collezione.

Oppure posso fare qualcosa di simile, ma forse un pochino più pulito:

# view - collection of objects 
= render 'posts', posts: @posts 

# view - object 
= render @post 

# posts/posts.haml 
%ul 
    = render post 

# posts/post.haml 
- post_counter ||= false 
- tag = post_counter ? :li : :div 
= content_tag tag do 
    = post.body 

Questo è il modo migliore/più pulito che posso venire con finora, tutti i pensieri?

risposta

1

Aggiungi un altro parziale che rende il tag li e poi invoca il parziale regolare:

  • app/views/messaggi/index.html. haml

    %ul.posts= render collection: @posts, partial: "posts/post_li" 
    
  • app/views/messaggi/_post_li.html.haml

    %li= render post 
    
  • app/views/messaggi/_post.html.haml

    = div_for post do 
        .... 
    
1

È possibile avere un singolo parziale e all'interno del parziale può solo verificare se il locale passato ad esso è una raccolta o un singolo oggetto Post.

# Render calls 
render :partial => "posts/display_posts", :locals => {:posts => Post.first} 
render :partial => "posts/display_posts", :locals => {:posts => Post.all} # collection 

E la tua parziale:

- if posts.is_a? Post # single item 
    %div= posts.body 
- else 
    %ul 
    - posts.each do |post| 
    %li= post.body 
+1

Grazie. Sfortunatamente, perché per ogni post non avrei solo renderizzato "post.body", sarebbe un grosso pezzo di div e As and span, il loro ripetersi parziale sembra unideale. Suppongo di poter fare '- se posts.is_a? Post = content_tag (: div) do else = content_tag (: ul) do = content_tag (: li) do 'ma poi il rientro sarebbe incasinato a meno che non prendessi il post.body html in qualcos'altro (ad esempio, un altro parziale). –