проблема отношений во взглядах / контроллере - PullRequest
1 голос
/ 18 ноября 2010

У меня есть две модели (упрощенно), аналогичные этой:

RECIPE (has_one video)

  • id
  • имя
  • Descripion

ВИДЕО (принадлежит к рецепту)

  • ID
  • ссылка
  • recipe_id

В RecipesController # new я отображаю представление для создания ресурса. Я использую form_for @recipe, со всеми обычными f.helpers

Дело в том, что мне нужно поле для заполнения атрибута ссылки, и оно принадлежит другому объекту (видео). Итак, поскольку f.helpers префиксует все с ресурсом [field], я использовал обычную ссылку text_field_tag: *.

Пока все прошло гладко. В RecipesController # create я делаю:

@recipe = Recipe.new(params[:recipe])<br> @recipe.video = Video.new(params[:link])

чтобы назначить видео рецепту.

После этого я делаю обычный @ recipe.save, и вот где я застрял.

Я ожидал, что если видео содержит какие-либо ошибки, рецепт не сохранится, и я смогу использовать объект @ recipe.errors для получения всех ошибок (также из видео).

Но не только сохранение рецептов, @ recipe.errors не содержит сообщений из видео. Я использовал (частичные «ошибки»,: object => @recipe), чтобы вывести список всех сообщений, но это не подберет те сообщения, которые были вызваны видеообъектом.

Я пробовал разные вещи, например, внутри частичного у меня было условие, которое первоначально проверялось:

if object.errors.any?
 object.errors.full_messages ...
end

Я поменял его на:

if (object.errors.merge! (Object.video.errors)). Any? но это не сработало, к сожалению.

Что мне делать в такой ситуации? Как предотвратить сохранение @recipe при наличии ошибок в видео и как их без проблем перечислить вместе?

1 Ответ

1 голос
/ 18 ноября 2010

Работа с вложенными объектами требует небольшой работы, но это не так сложно.Начиная с Rails 2.3, существует понятие «вложенные атрибуты» и «формы вложенных объектов» (см .: http://guides.rubyonrails.org/2_3_release_notes.html#nested-attributes и http://guides.rubyonrails.org/2_3_release_notes.html#nested-object-forms).

В основном это позволяет вам делать что-то вроде этого:

<% form_for @recipe do |f| %>
  <%= f.text_field :name %>
  <%= f.text_field :description %>
  <% f.fields_for :video do |v| %>
    <%= v.text_field :link %>
  <% end %>
<% end %>

Как вы видите, код сообщает форме, что в рецепте есть fields_for a: video объект. Затем вы можете изменить свой рецепт следующим образом:

class Recipe < ActiveRecord::Base
  has_one :video
  accepts_nested_attributes_for :video
end

ThisКод сообщает ActiveRecord, что вы можете передать атрибуты для видеообъекта вместе с рецептом. Так что теперь все, что вам нужно сделать, это ...

Recipe.create(params[:recipe])

... и он создаст рецепт ивидеозаписи, так как ваша форма содержит видеоинформацию и класс Recipe accepts_nested_attributes_for: video.

-

Просто чтобы прояснить пару вещей о вашем коде. Вы передаете в параметрах [: link] to Video.new. Video.new не ожидает строку, он ожидает хэш атрибутов. Итак, вы звоните ...

Video.new("example.com/video_file.mp4")

... когда вы действительно хотите бытьпроходя в..

Video.new(:link => "example.com/video_file.mp4")

без бПомимо хэша, ActiveRecord не знает, какой атрибут вы пытаетесь установить с помощью «new».Вы могли бы также сделать.,.

v = Video.new
v.link = params[:link]

.,,и установить атрибут таким образом.Кроме того, в зависимости от того, что еще было в контроллере, вы, возможно, не назначаете recipe_id для видео и не можете звонить @ video.save.Иногда из-за крутости ActiveRecord кажется, что таких вещей не должно быть - и если вы используете что-то вроде acceptpts_nested_attributes_, вам не нужно делать такие вещи.Однако, если вы хотите сделать это вручную, вы должны обязательно сохранить их все, назначить ассоциации, проверить оба объекта на наличие ошибок и управлять транзакцией.

-

Документация Rails по этому вопросу неплохая и включает в себя многое из этого: http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

Райан Дейгл также имеет хороший пост в блоге: http://ryandaigle.com/articles/2009/2/1/what-s-new-in-edge-rails-nested-attributes

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...