在 has_and_belongs_to_many 关系中保存依赖对象的最佳方法?

发布于 2024-11-09 22:07:56 字数 1868 浏览 0 评论 0原文

您好,我是 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)

它,就会在标签表中创建重复的记录(即使 :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   

这是应该完成的方式吗?

这看起来很昂贵(特别是因为它在循环中)所以我想知道是否有另一种“更干净”的方法来做到这一点? (请忘记操作的干燥等等)

是否有一种干净的方法来创建我的标签,而无需手动检查重复项?

预先感谢您的帮助!

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 is 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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

遥远的她 2024-11-16 22:07:56

您可以通过将 Accepts_nested_attributes_for 添加到 Post 模型来自动保存帖子的标签属性

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

下一步是在帖子表单中输出标签字段。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文