Создание вложенных объектов — игнорировать сохранение, если они уникальны, но все еще создают дочерние элементы

#ruby-on-rails #ruby-on-rails-3

#ruby-on-rails #ruby-on-rails-3

Вопрос:

У меня возникли некоторые трудности с созданием вложенных объектов между отношениями «один ко многим». Мои модели — исполнитель и песня, у исполнителя может быть много песен, и песня должна принадлежать исполнителю.

У меня возникают проблемы с созданием исполнителей и песен. Для удобства пользователей я хочу, чтобы пользователи создавали песни исполнителя одновременно с созданием исполнителя, поэтому мой контроллер Artist выглядит следующим образом:

 def new
    @artist = Artist.new
    @artist.songs.build
  end

  def create
    @artist = Artist.new(params[:artist])

    if @artist.save
      redirect_to root_path
    else
      render :action => 'new'
    end
  end
  

и затем форма:

 <div>
    <%= f.label :name, "Artist" %>
    <%= f.text_field :name %>
  </div>  

  <%= f.fields_for :songs do |song| %>
  <div>
    <%= song.label :title, "Song" %>
    <%= song.text_field :title %>
  </div>
  <% end %>
  

В моей модели Artist я в настоящее время проверяю уникальность имени и хочу продолжать это делать. Что я пытаюсь выяснить, так это найти способ, чтобы, если пользователь переходит к этой форме, исполнитель с таким именем уже существовал, игнорировать сохранение исполнителя, но вместо этого использовать что-то вроде этого:

 @artist = Artist.find_by_name(params[:artist_name])
 @song = @artist.songs.new
  

Где новая песня создается для существующего исполнителя. Я могу сделать это сейчас, добавив ссылку и используя мой контроллер песен / views. Я не понимаю, как я мог бы сделать это без пользовательского ввода и просто создавать песни.

Должен ли я использовать Javascript для отправки запроса post, если имя исполнителя существует вместе с информацией о песне? Я мог бы также добавить логику в контроллер, но не знаю, как добавить условия, основанные на проверке в контроллере, для меня это тоже довольно плохо пахнет. Есть ли у кого-нибудь опыт работы с подобной ситуацией? Ценю помощь.

Ответ №1:

Здесь вы владеете довольно страшным мечом. При проверке по имени исполнителя можете ли вы быть уверены, что песня не может быть для другого исполнителя с тем же именем? Потому что, если ваш проект широкий, вы неизбежно будете пересекать данные.

Что я бы рекомендовал, так это не проверять это постфактум, а, скорее, когда пользователи вводят имя исполнителя, использовать плагин автозаполнения jQuery, такойhttp://jqueryui.com/demos/autocomplete / чтобы пользователь мог выбрать этого исполнителя, если они уже есть.

Если пользователь вводит имя исполнителя, и этот исполнитель уже существует (использование find_by_name подходит), тогда я бы перенаправил их на промежуточную страницу с уведомлением, в котором говорится: «Исполнитель с таким именем уже существует. Это тот исполнитель, которого вы ищете?» с некоторой базовой информацией от исполнителя, найденной в вашей базе данных. Тогда у вас может быть 2 ссылки: одна, которая говорит «Да» и помогает в создании, и одна, которая говорит «Нет, создайте нового исполнителя» и переходит оттуда.

С моей точки зрения, вы должны быть в состоянии делать все это с помощью rails и не нуждаться в какой-либо публикации ajax. Убедитесь, что вы следите за параметрами, передаваемыми со страницы на страницу. использование redirect или render изменяет это.