fields_for unable to pass in an array
I'm trying to do fields_for of a subset of objects and struggling some. Here are some details:
class Club < ActiveRecord::Base
has_many :shifts
...
<%= form_for club, :url => shift_builders_url do |f| %>
...
<% these_shifts = Shift.where(:club_id => club.id, :date => date) %>
<%= f.fields_for :shifts, these_shifts do |s| %>
<td><%= render "shift_fields", :f => s %></td>
<% end %>
...
So that code works basically as expected, though clearly it's awful to be making those calls in the view. To clean up the code, I added the following controller code:
...
@shifts_by_club_and_date = sort_shifts_by_club_and_date(@shifts)
...
private
def sort_shifts_by_club_and_date(shifts)
return_hash = Hash.new
shifts.each do |s|
return_hash["#{s.club_id}-#{s.date}"] ? return_hash["#{s.club_id}-#{s.date}"] << s : return_hash["#{s.club_id}-#{s.date}"] = [s]
end
return return_hash
end
Then when I do:
<%= form_for club, :url => shift_builders_url do |f| %>
...
<% these_shifts = @shifts_by_club_and_date["#{club.id}-#{date}"] %>
<%= f.fields_for :shifts, these_shifts do |s| %>
<td><%= render "shift_fields", :f => s %></td>
<% end %>
...
Instead of taking that array in, it does something like:
Shift Load (7.3ms) SELECT `shifts`.* FROM `shifts` WHERE (`shifts`.club_id = 2)
And then draws the fields for every single shift object for that club... Passing in an Arel object seems to work fine, but an array does not, it seems. What is the best way to have a fields_for draw just a subset of objects?
I've looked at this similar question, but I don't think I can do the association like has_many :shifts_on_day(date)....
Edit to add: I'm running Rails 3.0.开发者_Go百科7 on REE with MySQL
<%= form_for club, :url => shift_builders_url do |f| %>
...
<% these_shifts = club.shifts_for_date(some_date) %>
<%= f.fields_for :shifts, these_shifts do |s| %>
<td><%= render "shift_fields", :f => s %></td>
<% end %>
Model
class Club < AR::Base
has_many :shifts
...
def shifts_for_date(date)
shifts.where(:date => date)
end
...
end
try replacing:
<%= f.fields_for :shifts, these_shifts do |s| %>
<td><%= render "shift_fields", :f => s %></td>
<% end %>
with :
<% for shift in these_shifts do %>
<td><%= f.field_for :shift %></td>
<% end %>
I'm not sure, but it seems that these_shifts
is not what you expect, then when fields_for
parses the arguments it checks that there is something there, and not finding what you are looking for it do call(:shields)
on the club as you where doing f.fields_for :shields, nil do |s|
. (see https://github.com/rails/rails/blob/30c67000cab2284689bd93f25937c088d1ec6e74/actionview/lib/action_view/helpers/form_helper.rb#L1943)
精彩评论