为什么我的每个帖子都有相同集合名称的重复项

发布于 2024-12-08 01:15:43 字数 1650 浏览 0 评论 0原文

您好,我有一个帖子模型和一个集合模型,通过集合模型连接在一起。当用户发布帖子时,他会将帖子添加到集合中,例如“音乐”。然而,当我列出所有用户的收藏时,每个帖子都有多个“音乐”条目,而不是只有 1 个。 我正在使用 @collections = @user.posts.map(&:collections).flatten 获取集合,如果我在末尾添加 .uniq 则不会出现重复项 (@collections = @user.posts.map(& :collections).flatten.uniq)但是有人可以解释为什么我必须这样做吗???多谢。

UsersController

  def show
    @user = User.find(params[:id]) rescue nil
    @posts = @user.posts.paginate(:per_page => "10",:page => params[:page])
    @title = @user.name
    @collections = @user.posts.map(&:collections).flatten
  end

views/users/show.html.erb

 <h1>Collections</h1>

  <% @collections.each do |collection| %>
    <%= link_to collection.name, user_collection_posts_path(@user, link_name(collection)) %><br />
  <% end %>

集合模型

class Collection < ActiveRecord::Base
  mount_uploader :image, CollectionUploader
  attr_accessible :name, :image, :user_id
  has_many :collectionships
  has_many :users, :through => :posts
  has_many :posts, :through => :collectionships
end

collectionship 模型

class Collectionship < ActiveRecord::Base
  belongs_to :post
  belongs_to :collection
  has_one :user, :through => :post
  attr_accessible :post_id, :collection_id
end

帖子模型

  belongs_to :user
  has_many :collectionships
  has_many :collections, :through => :collectionships

user mdoel

has_many :posts, :dependent => :destroy
has_many :collections, :through => :posts

Hi I have a posts model and a collections model, joined together by a collectionship model. When a user makes a post he adds the post to a collection, such as 'music'. However, when I list all the user's collections there are multiple 'music' entries for each post made instead of just 1.
I'm grabbing the collections with @collections = @user.posts.map(&:collections).flatten, if I add a .uniq on the end get no duplicates (@collections = @user.posts.map(&:collections).flatten.uniq) But could someone explain why I'd have to do this??? Thanks a lot.

UsersController

  def show
    @user = User.find(params[:id]) rescue nil
    @posts = @user.posts.paginate(:per_page => "10",:page => params[:page])
    @title = @user.name
    @collections = @user.posts.map(&:collections).flatten
  end

views/users/show.html.erb

 <h1>Collections</h1>

  <% @collections.each do |collection| %>
    <%= link_to collection.name, user_collection_posts_path(@user, link_name(collection)) %><br />
  <% end %>

collection model

class Collection < ActiveRecord::Base
  mount_uploader :image, CollectionUploader
  attr_accessible :name, :image, :user_id
  has_many :collectionships
  has_many :users, :through => :posts
  has_many :posts, :through => :collectionships
end

collectionship model

class Collectionship < ActiveRecord::Base
  belongs_to :post
  belongs_to :collection
  has_one :user, :through => :post
  attr_accessible :post_id, :collection_id
end

post model

  belongs_to :user
  has_many :collectionships
  has_many :collections, :through => :collectionships

user mdoel

has_many :posts, :dependent => :destroy
has_many :collections, :through => :posts

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

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

发布评论

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

评论(1

表情可笑 2024-12-15 01:15:43

你已经找到了导致这种情况的线路。以下是我对为什么您看到自己所做的事情的看法(只是该行评估的每个步骤的扩展):

@user.posts #=>
[
    <Post1:
        id: 1492
        collections: ['history', 'spain']
    >,
    <Post2:
        id: 1912
        collections: ['history', 'shipwrecks']
    >
]

@user.posts.map(&:collections) #=>
[
    ['history', 'spain'],
    ['history', 'shipwrecks']
]

@user.posts.map(&:collections).flatten #=>
[
    'history',
    'spain',
    'history',
    'shipwrecks'
]

因此您可以看到,对于每个帖子, post.collections 返回 发布的所有集合(理应如此)。 flatten 方法并不关心是否存在重复项 - 它只关心返回单个一维数组。因此,除非您对最终产品调用 uniq ,否则这些重复项将在整个操作过程中保留下来。

我相信也有一种 ActiveRecord 方法可以避免这种情况:如果用户 has_many :collections,则 @user.collections 不应该有任何重复项。不过,可能是一个丑陋的 AR 宏,具有如此多的继承级别。

无论如何,希望有帮助!

You've got the line that's causing it. Here's my take on why you're seeing what you do (just an expansion of each step of evaluation of that line):

@user.posts #=>
[
    <Post1:
        id: 1492
        collections: ['history', 'spain']
    >,
    <Post2:
        id: 1912
        collections: ['history', 'shipwrecks']
    >
]

@user.posts.map(&:collections) #=>
[
    ['history', 'spain'],
    ['history', 'shipwrecks']
]

@user.posts.map(&:collections).flatten #=>
[
    'history',
    'spain',
    'history',
    'shipwrecks'
]

So you can see that each for each post, post.collections returns all the collections that post is in (as it should). And the flatten method doesn't care if there are duplicates or not - it just cares about returning a single, 1-D array. So those duplicates survive throughout the whole operation, unless you call uniq on the final product.

I believe there's an ActiveRecord way to avoid this as well: If a User has_many :collections, then @user.collections shouldn't have any duplicates. Might be an ugly AR macro, though, with so many levels of inheritance.

Anyway, hope that helps!

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