2015-06-12 2 views
0

Как установить поле позиции в атрибутах для вложенной модели, чтобы мои отношения has_many запоминали порядок сортировки?Установить значение позиции из индекса для вложенных атрибутов модели

Я хочу установить позицию из индекса так, чтобы он отражал порядок, в который были втянуты отношения.

У меня есть форма с вложенными полями, используя драгоценный камень кокона с JQuery Sortable, позволяющий каждому набору полей быть перетаскиваемым.

Я хочу обновить порядок всех полей при сохранении формы.

+0

Каковы имена двух классов моделей в ваших отношениях? –

+0

@MaxWilliams - резюме и образование. резюме has_many education – Will

ответ

0

Если у вас есть стандартные маршруты CRUD/restful и настройки контроллера, то все, что вы хотите сделать, это вызвать «update_attributes (: position => 3)» на экземпляре вложенного класса (образование в этом дело).

Обычный маршрут для обновления образования, который вложен в «резюме» будет

UPDATE /resumes/123/educations/456 

так, вы будете делать в Ajax вызов этой ссылке. Метод «UPDATE» на самом деле не является методом обновления, он вроде подделан, передавая параметр "_method" = "UPDATE", поэтому ваш вызов ajax также должен будет включить этот параметр.

Таким образом, в основном, на «закончил тащит» событие, вы собираетесь делать вызов Ajax для этого URL

"/resumes/<%= @resume.id %>/educations/<%= education.id %>" 

и передачи данных, как

{"_method": "UPDATE", "education[position]": <new position>} 

Это должно обновить положение объекта образования.

Другая оставшаяся проблема заключается в том, что при изменении положения одного элемента мы сможем сменить act_as_list, и мы хотим, чтобы остальные также автоматически настраивали свое положение. Я не уверен, что act_as_list делает это автоматически. Попробуй.

+0

спасибо. Однако я хочу установить порядок сохранения формы. – Will

+0

ах, когда вы сказали, что используете jquery sortable, я предположил, что вы делаете ajax-вызовы всякий раз, когда пользователь заканчивает перетаскивание элемента. –

0

Хорошо, неаяя версия.

Предположим, что ваша форма является form_for @resume, что означает, что она будет вызывать резюме # создавать или возобновлять действие # update.

Если все education строки в списке имеют скрытое поле, как этот

<%= hidden_field_tag "resume[education_ids][]", education.id %> 

тогда, когда форма была отправлена, они будут проходить в массив в Params [: резюме] [: education_ids] в том порядке, в котором они появляются на странице, когда форма была отправлена ​​, что вам и нужно.

Ассоциация дает вам метод сеттера. Возобновляет # education_ids, что позволяет вам устанавливать ассоциации в порядке, таким образом.

Т.е., ваше действие обновления (если это нормальное действие обновления) можно сказать что-то вроде

@resume = Resume.find_by_id(params[:id]) 
if @resume.update_attributes(params[:resume]) 
    ... 

в этом случае, это будет говорить

@resume.update_attributes(:education_ids => [5,6,2,1]) 

, который, как говорят «набор мои образования будут теми, у которых есть идентификаторы 5,6,2,1, в этом порядке.

CAVEAT: в моей версии рельсов (это может быть исправлено в следующей версии), если вы используете этот метод _ids, и он ужеимеет ассоциации, но в другом порядке он НЕ переупорядочивает их. Дайте ему понять, что происходит.

+0

Благодаря @MaxWilliams - форма может добавлять и удалять учебные предметы, а также изменять их порядок. Вот почему мне нужно занять позицию для каждой записи образования из ее позиции в параметрах. Это индекс. – Will

+0

Так что это не сработает. Я не знаю идентификаторов всех записей. на самом деле у некоторых нет идентификатора для сохранения, потому что они новы. – Will

+0

Вам нужно объяснить этот материал, то есть ваши требования, в вашем вопросе. Я предполагаю, потому что вы не даете никаких подробностей о том, что хотите. –

0

Это не может быть лучший способ сделать это, но у меня это работает в моем контроллере.

p = 1 
experiences = [] 
params[:user][:resume_attributes][:experiences_attributes].each do |e|   
    e = e.last.merge(:position=>p) 
    experiences << e 
    p = p + 1 
end 
params[:user][:resume_attributes][:experiences_attributes] = experiences  

, что, по крайней мере, иллюстрирует то, что я хочу достичь.

+0

Можете ли вы скопировать некоторые примерные значения для 'params [: user]' в этот ответ, пожалуйста, чтобы мы могли видеть, что здесь происходит? –

1

Попробуйте использовать драгоценный камень "act_as_list".

class TodoList < ActiveRecord::Base 
    has_many :todo_items, -> { order(position: :asc) } 
end 

class TodoItem < ActiveRecord::Base 
    belongs_to :todo_list 
    acts_as_list scope: :todo_list 
end 

todo_list = TodoList.find(...) 
todo_list.todo_items.first.move_to_bottom 
todo_list.todo_items.last.move_higher 

См: https://github.com/swanandp/acts_as_list

Смежные вопросы