我对两个模型之间的匹配感到困惑。我已经研究了stackoverflow和google,直到2天了,但是没有办法... 关于匹配和过滤还有更多的问题和答案,但这只是一种搜索,列出的方式。可能是我不确定我不确定。 例如: 我的应用程序中包含内容和用户。 我分享了内容,但不想让所有用户都喜欢它。 用户应该看到谁;
我的第一个想法是为用户创建个人资料并从他们那里获取信息。
另外,为Content
模型创建配置文件过滤器,并填写像belov这样的表格。
但是问题已经到了最后一步;
“我如何比较它们,只有用户才能看到并喜欢谁具有与Content
过滤器属性相同的真实属性。
模型;
User
和Content
Profile
所属user
Contentfilter
所属Content
比; 如果current_user配置文件属性与“内容”过滤器相同,则显示内容。
您有什么建议吗? 谢谢。
答案 0 :(得分:0)
我将假设您的意思是任何匹配的内容,但我将为所有或任何匹配的配置文件过滤器提供解决方案。
这是关于如何实现所需目标的一种快速解决方案。
给出以下模型:
# app/models/user.rb
class User < ApplicationRecord
has_one :profile, as: :profilable
def all_matching_content
profile: Profile.where(
"? >= age", profile.age).
where(
gender: profile.gender,
city: profile.city,
license: profile.license).
where(profilable_type: "Content"))
end
def any_matching_content
Content.where(
profile: Profile.where("? >= age", profile.age).
or(Profile.where(gender: profile.gender)).
or(Profile.where(city: profile.city)).
or(Profile.where(license: profile.license)).
where(profilable_type: "Content"))
end
end
end
# app/models/profile.rb
class Profile < ApplicationRecord
belongs_to :profilable, polymorphic: true, optional: true
end
# app/models/content.rb
class Content < ApplicationRecord
has_one :profile, as: :profilable
end
以及以下迁移:
# db/migrate/20181114004031_create_users.rb
class CreateUsers < ActiveRecord::Migration[5.2]
def change
create_table :users do |t|
t.string :name, index: true
t.timestamps
end
end
end
# db/migrate/20181114004134_create_profiles.rb
class CreateProfiles < ActiveRecord::Migration[5.2]
def change
create_table :profiles do |t|
t.references :profilable, polymorphic: true, null: true
t.boolean :license, index: true
t.string :city, index: true
t.string :gender, index: true
t.integer :age, index: true
t.timestamps
t.index [:license, :city, :gender, :age], name: "profile_composite_index"
end
end
end
# db/migrate/20181114004307_create_contents.rb
class CreateContents < ActiveRecord::Migration[5.2]
def change
create_table :contents do |t|
t.string :title, index: true
t.timestamps
end
end
end
以及以下种子:
# db/seeds.rb
User.create!(
name: "John",
profile: Profile.create!(
license: true,
city: "London",
gender: "Male",
age: 19
)
)
User.create!(
name: "Jane",
profile: Profile.create!(
license: false,
city: "London",
gender: "Female",
age: 17
)
)
User.create!(
name: "Rose",
profile: Profile.create!(
license: true,
city: "Edinburgh",
gender: "Female",
age: 21
)
)
User.create!(
name: "Hans",
profile: Profile.create!(
license: true,
city: "Berlin",
gender: "Male",
age: 24
)
)
Content.create!(
title: "London introduces new tax",
profile: Profile.create!(
city: "London"
)
)
Content.create!(
title: "New license requirements in Berlin",
profile: Profile.create!(
city: "Berlin",
license: true
)
)
Content.create!(
title: "Women should get new immunization",
profile: Profile.create!(
gender: "Female"
)
)
Content.create!(
title: "Adults only expo opens Wednesday",
profile: Profile.create!(
age: 18
)
)
您将能够执行以下操作:
> john = User.find_by(name: "John")
> john.all_matching_content
=> #<ActiveRecord::Relation []>
> john.any_matching_content.map(&:title)
=> ["London introduces new tax", "New license requirements in Berlin", "Adults only expo opens Wednesday"]
> jane = User.find_by(name: "Jane")
> jane.any_matching_content.map(&:title)
=> ["London introduces new tax", "Women should get new immunization"]
> rose = User.find_by(name: "Rose")
> rose.any_matching_content.map(&:title)
=> ["New license requirements in Berlin", "Women should get new immunization", "Adults only expo opens Wednesday"]
> hans = User.find_by(name: "Hans")
> hans.any_matching_content.map(&:title)
=> ["New license requirements in Berlin", "Adults only expo opens Wednesday"]
该解决方案通过与Profile
和User
共享多态Content
模型来工作。然后,通过将用户的Content
属性传递给查询来查询属于User
类型的配置文件,它将Profile
与Content
实例进行匹配。
请注意,#all_matching_content
方法要求所有配置文件属性都匹配,基本上这意味着查询中的所有条件都经过“与”运算。 #any_matching_content
方法改为使用“ OR”条件。
我已将一个快速项目上传到GitHub,该示例已被编码: