开发者

best way to save dependent objects in a has_and_belongs_to_many relation?

开发者 https://www.devze.com 2023-03-08 23:00 出处:网络
Hi I am new to rails and I would like to know what is the best way who save dependent objects in an HBTM relation.

Hi I am new to rails and I would like to know what is the best way who save dependent objects in an HBTM relation.

Specifically, I have two classes Post and Tag

class Post < ActiveRecord::Base
  has_and_belongs_to_many :tags
end

class Tag < ActiveRecord::Base
  has_and_belongs_to_many :posts
end

I have a migration to create the joining table

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

All i开发者_Python百科s good up to here

So I have a PostsController from which I handle the creation, updates and deletes for the posts, and I want to encapsulate the Tags so that the creation is via the PostsController... like so:

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

I am not sure how I should handle the creation of my Tag(s) because if I just call

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

this will create duplicate records in the Tags table (even when :uniq => true is specified in the model).

So to avoid the duplication I see if a tag is already present and then add it like this

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

Is this the way it's supposed to be done?

This seems expensive (especially 'cause it's in a loop) so I am wondering if there is another "cleaner" way to do this? (pls forget the DRY'ing up of the action and so on)

Is there a clean way to create my Tags without having to manually check for duplicates?

thank you in advance for your help!


You can save tags attribute of post if automatically by adding accepts_nested_attributes_for to Post model

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

The next step is to output tags fields inside post form.

0

精彩评论

暂无评论...
验证码 换一张
取 消