Ruby on rails Rails-多态收藏夹(用户可以收藏不同的型号)

Ruby on rails Rails-多态收藏夹(用户可以收藏不同的型号),ruby-on-rails,rails-activerecord,polymorphic-associations,activemodel,Ruby On Rails,Rails Activerecord,Polymorphic Associations,Activemodel,我们正在尝试添加多个favoritable对象,其中用户可以喜欢许多不同的对象,但不确定如何使其工作 以下是最喜欢的型号: class Favorite < ActiveRecord::Base # belongs_to :imageable, polymorphic: true belongs_to :user belongs_to :category belongs_to :business belongs_to :ad_channel belongs_to :

我们正在尝试添加多个favoritable对象,其中用户可以喜欢许多不同的对象,但不确定如何使其工作

以下是最喜欢的型号:

class Favorite < ActiveRecord::Base
  # belongs_to :imageable, polymorphic: true
  belongs_to :user
  belongs_to :category
  belongs_to :business
  belongs_to :ad_channel
  belongs_to :location
  belongs_to :offer
end
class收藏夹
用户模型:

class User < ActiveRecord::Base
  has_many :favorites, as: :favoritable
end
class用户
还有一个例子,是人们喜欢的东西:

class Category < ActiveRecord::Base
  has_many :sub_categories
  has_many :ad_channels
  has_many :offers
  belongs_to :favoritable, polymorphic: true
end
类别
我不确定这是否设置正确,因此这将是我们需要反馈的第一件事

其次,我们如何“喜爱”用户的东西

这是我们迄今为止尝试过但未成功的方法:

@user.favorites << Category.find(1)
@user.favorites模型关系
您喜爱的
型号如下所示:

class Favorite < ActiveRecord::Base
  belongs_to :favoritable, polymorphic: true
  belongs_to :user, inverse_of: :favorites
end
class User < ActiveRecord::Base
  has_many :favorites, inverse_of: :user
end
class Category < ActiveRecord::Base
  has_many :favorites, as: :favoritable
end
add_index :favorites, [:favoritable_id, :favoritable_type], unique: true
然后,可以推荐的模型应该如下所示:

class Favorite < ActiveRecord::Base
  belongs_to :favoritable, polymorphic: true
  belongs_to :user, inverse_of: :favorites
end
class User < ActiveRecord::Base
  has_many :favorites, inverse_of: :user
end
class Category < ActiveRecord::Base
  has_many :favorites, as: :favoritable
end
add_index :favorites, [:favoritable_id, :favoritable_type], unique: true
请记住,您需要将
收藏夹
的实例添加到
@user.favorites
,而不是
收藏夹
模型的实例。
favoritable
模型是
Favorite
实例上的一个属性

但实际上,在Rails中实现这一点的首选方法如下:

@user.favorites.build(favoritable: Category.find(1))
寻找某种最爱 如果您只想查找特定类型的收藏夹,可以执行以下操作:

@user.favorites.where(favoritable_type: 'Category')  # get favorited categories for user
Favorite.where(favoritable_type: 'Category')         # get all favorited categories
如果您打算经常这样做,我认为向多态模型添加作用域非常简单:

class Favorite < ActiveRecord::Base
  scope :categories, -> { where(favoritable_type: 'Category') }
end
这将获得与上面的
@user.favorites.where(favoritable_type:'Category')
相同的结果

允许用户仅收藏一次项目 我猜您可能还希望允许用户只能收藏一个项目一次,这样您就不会在执行类似于,
@user.favorites.categories的操作时获得重复的类别。以下是如何在您喜爱的
车型上设置该选项:

class Favorite < ActiveRecord::Base
  belongs_to :favoritable, polymorphic: true
  belongs_to :user, inverse_of: :favorites

  validates :user_id, uniqueness: { 
    scope: [:favoritable_id, :favoritable_type],
    message: 'can only favorite an item once'
  }
end
否则,把这些线放到迁移中,运行那个坏男孩

在进行此操作时,应该确保所有外键都有索引。在本例中,这将是
收藏夹
表上的
用户id
列。同样,如果您不确定,请检查您的模式文件

关于数据库索引,还有最后一件事:如果要添加上面一节中概述的唯一性约束,那么应该向数据库添加唯一性索引。您可以这样做:

class Favorite < ActiveRecord::Base
  belongs_to :favoritable, polymorphic: true
  belongs_to :user, inverse_of: :favorites
end
class User < ActiveRecord::Base
  has_many :favorites, inverse_of: :user
end
class Category < ActiveRecord::Base
  has_many :favorites, as: :favoritable
end
add_index :favorites, [:favoritable_id, :favoritable_type], unique: true

这将在数据库级别强制执行唯一性约束,如果您有多个应用程序服务器都使用单个数据库,这是必需的,而且通常是正确的操作方式。

这非常有效。什么是倒数:实际上是什么意思?在我看来,它实际上有点愚蠢,因为它应该自动发生,但是
reverse\u of
基本上告诉Rails这两个关系是彼此的倒数。这可以防止Rails在内存中创建重复的记录。在此阅读更多:再次感谢。还有一个问题,你将如何获取受欢迎的类别?任何用户都喜欢的类别,或者某个用户喜欢的类别?非常感谢。我们非常感谢分享如此详细的信息。但愿我能送你一些金子什么的