您好我是rails的新手,我想知道在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)
这将在Tags表中创建重复记录(即使在模型中指定了:uniq =&gt; true)。
为了避免重复,我看到标签是否已经存在,然后像这样添加
tag = Tag.find_by_name(t);
if tag.nil?
@post.tags.create!(:name => t)
else
@post.tags << tag #just create the association
end
这是应该做的吗?
这看起来很昂贵(特别是'因为它在循环中)所以我想知道是否有另一种“更清洁”的方法来做到这一点? (请忘记干活动等等)
是否有一种干净的方式来创建我的标签而无需手动检查重复项?
提前感谢您的帮助!
答案 0 :(得分:2)
您可以通过在posts模型中添加accepts_nested_attributes_for来自动保存帖子的标签属性
class Post < ActiveRecord::Base
has_and_belongs_to_many :tags
accepts_nested_attributes_for :tags
end
下一步是在帖子表格中输出标签字段。