почему у меня есть дубликаты для каждого сообщения с тем же именем коллекции - PullRequest
0 голосов
/ 04 октября 2011

Привет, у меня есть модель постов и модель коллекций, объединенная моделью коллекций. Когда пользователь создает сообщение, он добавляет сообщение в коллекцию, например «музыка». Однако, когда я перечисляю все коллекции пользователя, для каждого поста создается несколько записей «музыка» вместо 1. Я собираю коллекции с помощью @collections = @ user.posts.map (&: collection) .flatten, если я добавлю .uniq в конце, не получаю дубликатов (@collections = @ user.posts.map (&: Collection ) .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

просмотров / пользователей / 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

коллекционная модель

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

пользователь mdoel

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

1 Ответ

1 голос
/ 04 октября 2011

У вас есть линия, которая вызывает это. Вот мое мнение о том, почему вы видите, что делаете (просто расширение каждого этапа оценки этой линии):

@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 с таким количеством уровней наследования.

В любом случае, надеюсь, это поможет!

...