лучший способ сохранить зависимые объекты в отношении has_and_belongs_to_many? - PullRequest
0 голосов
/ 27 мая 2011

Привет, я новичок в рельсах, и я хотел бы знать, как лучше всего сохранить зависимые объекты в отношении HBTM.

В частности, у меня есть два класса Post и Tag

class Post < ActiveRecord::Base
  has_and_belongs_to_many :tags
end

class Tag < ActiveRecord::Base
  has_and_belongs_to_many :posts
end

У меня есть миграция для создания соединительной таблицы

class AddPostsTagsJoinTable < ActiveRecord::Migration
  def self.up
     create_table :posts_tags, :id => false do |t|
        t.integer :post_id
        t.integer :tag_id
      end
  end

  def self.down
    drop_table :postss_tags
  end
end

Здесь все хорошо

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

class PostsController < ApplicationController

  #... code removed for brevity

  def create
    @post  = current_user.posts.build(params[:post])
    if @post.save

      tag_names = params[:post][:tags].strip.split(' ')
      tag_names.each do |t|   

        #see if the tag already exists
        tag = Tag.find_by_name(t);
        if tag.nil?        
          @post.tags.create!(:name => t)
        else
          @post.tags << tag #just create the association
        end   

      end

      flash[:success] = "Post created."
      redirect_to(user_posts_path(current_user.username))
    else
      @user = current_user
      render 'new'
    end
  end

end

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

@post.tags.create!(:name => t)

это создаст дубликаты записей в таблице тегов (даже если в модели указано: uniq => true).

Поэтому, чтобы избежать дублирования, я вижу, присутствует ли уже тег, а затем добавляю его вот так

tag = Tag.find_by_name(t);
if tag.nil?        
  @post.tags.create!(:name => t)
else
  @post.tags << tag #just create the association
end   

Это так, как это должно быть сделано?

Это кажется дорогим (особенно потому, что оно в цикле), поэтому мне интересно, есть ли другой "более чистый" способ сделать это? (пожалуйста, забудьте про СУХОЕ действие и т. д.)

Существует ли чистый способ создания моих тегов без необходимости вручную проверять наличие дубликатов?

Заранее благодарю за помощь!

1 Ответ

2 голосов
/ 27 мая 2011

Вы можете сохранить атрибут тегов поста, если автоматически, добавив accepts_nested_attributes_for к модели поста

class Post < ActiveRecord::Base
  has_and_belongs_to_many :tags
  accepts_nested_attributes_for :tags
end

Следующим шагом является вывод полей тегов внутри поста.

...