2011-02-10 2 views
28

Я использую Rails 3.0.3 с ruby ​​1.9.2p0.Rails 3 fields_for - порядок сортировки теряется

В моей profiles_controller (функция редактирования) У меня есть этот вызов

@profile = Profile.find(params[:id]) 
@profile_items = @profile.profile_items.order("pos") 

, чтобы получить @profile_items в правильном порядке, отсортированные по «поз». В _form.html.erb я следующее

<% @profile_items.each do |pi| %> 
    <%= pi.pos %> | 
<% end %> 
<%= f.fields_for :profile_items do |f2| %> 
    <%= render 'profile_item_fields', :f => f2 %> 
<% end %> 

3 первых линий тестовый код, чтобы показать, что @profile_items находятся в правильном порядке. Но когда они оказываются, они потеряли отсортированный порядок!

Теперь у меня есть много для ответа, и я думаю, что это должна быть общая «ловушка» до .

Благодарен за любую помощь ...

ответ

42

Согласно документации Rails для fields_for, вы можете также указать объект записи после имени записи.

Так что-то, как это должно работать ...

<%= f.fields_for :profile_items, @profile_items do |f2| %> 
    <%= render 'profile_item_fields', :f => f2 %> 
<% end %> 
+20

Малые поправки. Если вы хотите сохранить сортировку записей, не делайте этого в ассоциации. Он будет извлекать материал из базы данных и удалять ваши временные записи (например, те, у которых ошибки не сохраняются). Поэтому вместо '@ profile_items.order ('position')' делаем что-то вроде этого: '@ profile_items.sort_by (&: position)'. – Grocery

+1

Многое, много, много, много, намного лучше, чем использование области по умолчанию. –

+0

... согласитесь с продуктом Grocery по проблеме, но поля-for неявны на основе «принимает вложенные атрибуты для» - поэтому не существует @profile_items (с использованием этого примера), когда-либо определенного. Итак, как сортировать неявно созданную коллекцию? Я нашел ответ здесь: https://stackoverflow.com/questions/10505853/how-to-maintain-the-ordering-for-nested-attributes-when-using-accepts-nested-att – JosephK

17

Это может быть достигнуто с помощью default_scope на вложенной модели:

class YourModel < ActiveRecord::Base 
    belongs_to :other_model 
    default_scope { order(:name) } 
end 
+0

Спасибо за это. Я потерял желание продолжить –

+0

Это лучший ответ на все, что я когда-либо видел. –

+0

Это хорошее решение, если вы всегда захотите отсортировать этот класс. Если вы в конечном итоге захотите заказать его другими способами, это может сделать вещи очень сложными (вам нужно каждый раз отбрасывать область по умолчанию), и лучше использовать ручной порядок или несколько областей с именем. –