在 Rails 中实现标签:如何用一个标签引用多个项目?

发布于 2024-11-29 15:51:00 字数 802 浏览 5 评论 0原文

我正在用 Rails 编写一个博客引擎,并设置了一个标签模型和一个帖子模型,它们具有 has_and_belongs_to_many 关系。标签添加工作正常,当查找具有特定标签的所有帖子时,问题就出现了:

如果我将标签“test”添加到帖子 A,然后将标签“test”添加到帖子 B,则有两个标签对象,名称均为“test” " 但 ID 不同,引用的帖子也不同。现在,如果我有一个控制器操作indexTagPosts,它接受参数“tag”并查找带有该标签的所有帖子,它只会返回一个帖子,因为另一个标签具有不同的ID并且没有真正关联。我应该以某种方式限制新标签的添加,还是应该以不同的方式操纵我提取所有相关标签的方式?

这是控制器操作,应该根据参数“标签”抓取所有相关帖子:

def indexTagPosts

        @tag = Tag.find(params[:tag])
        @posts = @tag.posts.all

end

这是保存标签的操作:

def create


    @post = Post.find(params[:post_id])
    @tag = @post.tags.create(params[:tag])

    respond_to do |format|
      if @tag.save
        format.html { redirect_to edit_post_path(@post),:notice => "Success" }
      end
    end  

end

提前致谢,并对冗余或错误措辞表示歉意。

I'm writing a blog engine in rails, and have set up a tag model and a post model which have a have_and_belongs_to_many relationship. Tag addition works fine, the problem comes when looking for all posts with a specific tag:

If I add tag "test" to Post A, then add tag "test" to post B, there are two tag objects, both with name "test" but with different IDs, both referencing different posts. Now if I have a controller action indexTagPosts which takes the parameter "tag" and finds all posts with that tag, it will only return one post, since the other tag has a different ID and is not really associated. Should I be somehow restricting the addition of new tags, or should I be manipulating the way I pull all relevant tags differently?

Here is the controller action which is supposed to grab all relevant posts based on the parameter 'tag':

def indexTagPosts

        @tag = Tag.find(params[:tag])
        @posts = @tag.posts.all

end

And here is the action to save a tag:

def create


    @post = Post.find(params[:post_id])
    @tag = @post.tags.create(params[:tag])

    respond_to do |format|
      if @tag.save
        format.html { redirect_to edit_post_path(@post),:notice => "Success" }
      end
    end  

end

Thanks in advance and apologies for redundancy or bad wording.

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

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

发布评论

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

评论(1

〆凄凉。 2024-12-06 15:51:00

我希望我知道每个人都是从哪里想到使用 has_and_belongs_to_many 的,因为这确实是一件很难管理的事情,即使一开始看起来很简单。更好的方法是拥有 has_many ..., :through 类型关系,因为您可以管理各个链接并向其轻松添加元数据。

例如,这是一个带有中间模型的简单双向连接,您会发现这种模式经常出现:

class Post < ActiveRecord::Base
  has_many :post_tags
  has_many :tags, :through => :post_tags
end

class Tag < ActiveRecord::Base
  has_many :post_tags
  has_many :posts, :through => :post_tags
end

class PostTag < ActiveRecord::Base
  belongs_to :post
  belongs_to :tag
end

此时添加和删除标签链接很简单:

@post = Post.find(params[:post_id])

if (params[:tags].present?)
  @post.tags = Tag.where(:name => params[:tags].split(/\s*,\s*/))
else
  @post.tags = [ ]
end

has_many 关系管理器将创建,根据需要更新或销毁 PostTag 关联模型。

一般来说,您将改进 Post 模型以包含一个实用方法,用于使用您喜欢的任何分隔符检索和分配标签:

 class Post
   def tags_used
     self.tags.collect(&:name).join(',')
   end

   def tags_used=(list)
     self.tags = list.present? ? Tag.where(:name => list.split(/\s*,\s*/)) : [ ]
   end
 end

I wish I knew where everyone got the idea to use has_and_belongs_to_many because it's a really difficult thing to manage, even if it seems simple at the start. The better approach is to have a has_many ..., :through type relationship because you can manage the individual links and add meta-data to them easily.

For instance, here is a simple two way join with an intermediate model, a pattern you'll find occurs quite often:

class Post < ActiveRecord::Base
  has_many :post_tags
  has_many :tags, :through => :post_tags
end

class Tag < ActiveRecord::Base
  has_many :post_tags
  has_many :posts, :through => :post_tags
end

class PostTag < ActiveRecord::Base
  belongs_to :post
  belongs_to :tag
end

Adding and removing Tag links at this point is trivial:

@post = Post.find(params[:post_id])

if (params[:tags].present?)
  @post.tags = Tag.where(:name => params[:tags].split(/\s*,\s*/))
else
  @post.tags = [ ]
end

The has_many relationship manager will create, update, or destroy the PostTag association models as required.

Generally you'll evolve the Post model to include a utility method for retrieving and assigning the tags using whatever separator you like:

 class Post
   def tags_used
     self.tags.collect(&:name).join(',')
   end

   def tags_used=(list)
     self.tags = list.present? ? Tag.where(:name => list.split(/\s*,\s*/)) : [ ]
   end
 end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文