Mam 2 przykładowe modele:
class Topic < ActiveRecord::Base
has_many :messages
accepts_nested_attributes_for :messages
end
class Message < ActiveRecord::Base
belongs_to :topic
end
Powiedzmy że, chciałbym zrobić przykładową aplikację przypominającą forum internetowe. W momencie kiedy tworzę nowy temat wywoływany jest controler Topic z metodą new
def new
@topic = Topic.new
@topic.messages.build
end
i w formularzu używam
fields_for :messages
Działa to zgodnie z oczekiwaniami, ale teraz nie wiem jaki jest “ruby way” aby na stronie wyświetlającej Topic wraz z Messages umożliwić dodanie nowego wpisu message.
Jeśli użyje fields_for to w formularzu pojawią mi się wszystkie istniejące wpisy do edycji, a tego bym nie chciał.
Mogę oczywiście stworzyć nowy kontroler do którego będzie przekazywana akcja, ale interesuje mnie jak to powinno być zrobione.
Znalazłem takie rozwiązanie, ale nie wiem czy ono jest do końca poprawne, bo przy większej ilości wiadomości to będzie jednak sporo iteracji.
def show
@topic = Topic.find(params[:id])
@topic.messages.build
end
<%= form_for @topic do |f| %>
<%= f.fields_for :messages do |ff| %>
<% if ff.object.new_record? %>
<div class="field">
<%= ff.label :text %><br>
<%= ff.text_area :text, cols: 160, rows: 10 %>
</div>
<% end %>
<% end %>
<% end %>
Wyświetlane jest teraz tylko pole do wprowadzenia nowej wiadomości, ale obawiam się o ilość iteracji jaka będzie musiała być wykonywana przy większej ilości wiadomości.
W takim razie może tylko tak?
def show
@topic = Topic.find(params[:id])
@new_message = @topic.messages.build
end
<%= form_for @topic do |f| %>
<%= f.fields_for :messages, @new_message do |ff| %>
<div class="field">
<%= ff.label :text %><br>
<%= ff.text_area :text, cols: 160, rows: 10 %>
</div>
<% end %>
<% end %>
Faktycznie. Dzięki wielkie.