Ruby on rails 一个关系与多个模型[有趣的rails关系概念]
我有一个应用程序,模型Ruby on rails 一个关系与多个模型[有趣的rails关系概念],ruby-on-rails,activerecord,orm,model,relationship,Ruby On Rails,Activerecord,Orm,Model,Relationship,我有一个应用程序,模型用户可以有多个“频道”。应用程序的频道部分必须易于扩展,每个频道都有自己的型号 我开始创建一个频道模型,其中属于用户关系与用户频道相反 我正在考虑使用类似的API: user = User.create(name: 'John') user.channels.create(name: 'google', account_id: '1234') # should create a GoogleChannel::Google Model user.channels.creat
用户可以有多个“频道”。应用程序的频道部分必须易于扩展,每个频道都有自己的型号
我开始创建一个频道
模型,其中属于用户
关系与用户
频道
相反
我正在考虑使用类似的API:
user = User.create(name: 'John')
user.channels.create(name: 'google', account_id: '1234') # should create a GoogleChannel::Google Model
user.channels.create(name: 'facebook', account_name: 'qwerty') # should create a FacebookChannel::Facebook Model
我在玩弄一个频道
模式,每个频道模式都有一个专门的模式,每个频道(谷歌、facebook等)都有一个与该模式的关系
更新:
我正在使用带有rails的mongoid,我不确定这是否有效。它使用STI
第一种方法:单表继承
class User << ApplicationRecord
has_many :channels
delegate :google_channels, :facebook_channels, :twitter_channels, to: :channels
end
class Channel << ApplicationRecord
belongs_to :user
self.inheritance_column = :brand
scope :google_channels, -> { where(brand: 'Google') }
scope :facebook_channels, -> { where(brand: 'Facebook') }
scope :twitter_channels, -> { where(brand: 'Twitter') }
def self.brands
%w(Google Facebook Twitter)
end
end
class GoogleChannel << Channel; end
class FacebookChannel << Channel; end
class TwitterChannel << Channel; end
class用户{where(品牌:'Facebook')}
范围:twitter_频道,->{where(品牌:'twitter')}
def自助品牌
%w(谷歌Facebook推特)
结束
结束
我不确定这是否有效。它使用STI
第一种方法:单表继承
class User << ApplicationRecord
has_many :channels
delegate :google_channels, :facebook_channels, :twitter_channels, to: :channels
end
class Channel << ApplicationRecord
belongs_to :user
self.inheritance_column = :brand
scope :google_channels, -> { where(brand: 'Google') }
scope :facebook_channels, -> { where(brand: 'Facebook') }
scope :twitter_channels, -> { where(brand: 'Twitter') }
def self.brands
%w(Google Facebook Twitter)
end
end
class GoogleChannel << Channel; end
class FacebookChannel << Channel; end
class TwitterChannel << Channel; end
class用户{where(品牌:'Facebook')}
范围:twitter_频道,->{where(品牌:'twitter')}
def自助品牌
%w(谷歌Facebook推特)
结束
结束
类GoogleChannel我假设您想要创建STI,其中User
有许多频道,因此在Rails 5中您可以尝试以下方法:
class User < ApplicationRecord
has_many :user_channels
has_many :channels, through: :user_channels
has_many :facebook_channels, class_name: 'FacebookChannel', through: :user_channels
has_many :google_channels, class_name: 'GoogleChannel', through: :user_channels
end
class UserChannel < ApplicationRecord
# user_id
# channel_id
belongs_to :user
belongs_to :channel
belongs_to :facebook_channel, class_name: 'FacebookChannel', foreign_key: :channel_id, optional: true
belongs_to :google_channel, class_name: 'GoogleChannel', foreign_key: :channel_id, optional: true
end
class Channel < ApplicationRecord
# You need to have "type" column to be created for storing different chanels
has_many :user_channels
has_many :users, through: :user_channels
end
class FacebookChannel < Channel
has_many :user_channels
has_many :users, through: :user_channels
end
class GoogleChannel < Channel
has_many :user_channels
has_many :users, through: :user_channels
end
然后你可以做你想要的当前用户.channels.facebook\u频道
channel\u type
列可以是字符串,也可以是整数(如果使用枚举)
此外,如果您创建visit
列(例如“布尔”),您可以执行current\u user.channels.where(visit:true)
或创建scope:visit\u true,->{where(visit:true)}
并执行类似current\u user.channels.visit\u true
你说呢?我假设你想创建一个STI,其中用户
有很多频道,所以在Rails 5中你可以尝试以下方法:
class User < ApplicationRecord
has_many :user_channels
has_many :channels, through: :user_channels
has_many :facebook_channels, class_name: 'FacebookChannel', through: :user_channels
has_many :google_channels, class_name: 'GoogleChannel', through: :user_channels
end
class UserChannel < ApplicationRecord
# user_id
# channel_id
belongs_to :user
belongs_to :channel
belongs_to :facebook_channel, class_name: 'FacebookChannel', foreign_key: :channel_id, optional: true
belongs_to :google_channel, class_name: 'GoogleChannel', foreign_key: :channel_id, optional: true
end
class Channel < ApplicationRecord
# You need to have "type" column to be created for storing different chanels
has_many :user_channels
has_many :users, through: :user_channels
end
class FacebookChannel < Channel
has_many :user_channels
has_many :users, through: :user_channels
end
class GoogleChannel < Channel
has_many :user_channels
has_many :users, through: :user_channels
end
然后你可以做你想要的当前用户.channels.facebook\u频道
channel\u type
列可以是字符串,也可以是整数(如果使用枚举)
此外,如果您创建visit
列(例如“布尔”),您可以执行current\u user.channels.where(visit:true)
或创建scope:visit\u true,->{where(visit:true)}
并执行类似current\u user.channels.visit\u true
你说什么?好像你在说STI或多态性?好像你在说STI或多态性?嗯。。。很有趣。我今天就试试是的,就是这样。每个品牌的模型(不同的表格)对我正在构建的应用程序最有意义。我希望我能得到像user.channel.model.visit
这样的API,并在频道模型上运行visit
方法(例如:GoogleChannel::Google
),而不指定我想要的频道类型(user.channels.Google\u channels
),但我不确定它是否有效(需要做一些修改)谢谢你,巴勃罗,但我认为我想要的是某种“魔力”。不知道是否有可能用我的方式来做。嗯。。。很有趣。我今天就试试是的,就是这样。每个品牌的模型(不同的表格)对我正在构建的应用程序最有意义。我希望我能得到像user.channel.model.visit
这样的API,并在频道模型上运行visit
方法(例如:GoogleChannel::Google
),而不指定我想要的频道类型(user.channels.Google\u channels
),但我不确定它是否有效(需要做一些修改)谢谢你,巴勃罗,但我认为我想要的是某种“魔力”。我不知道是否有可能用我的方式来做。嗯,更多的是多表关系。我希望有更多关于当前用户.channel.model的api,但不知道这是什么类型的模型。所以我不必猜测/找出它是谷歌频道还是facebook频道。顺便说一句,我使用的是mongoid,所以没有任何为我提供了很多关系:|@adrianthedev,请看我上面的更新。是的@matiss。我就是这么做的。这不是rails/AR/relationships的方式,但对我来说可以。现在我有了这个桥接模型通道
,每个通道都有不同的模型(因此我不会使通道
模型过载)。我遗憾的是没有关系问题。除非我将url
(或查询时可能需要的任何其他属性)属性存储到频道
模型中,否则我无法在不知道它是哪种频道的情况下执行当前用户.channels.where(url:'google.com')
。谢谢你的回答!嗯,更多的是多表关系。我希望有更多关于当前用户.channel.model的api,但不知道这是什么类型的模型。所以我不必猜测/找出它是谷歌频道还是facebook频道。顺便说一句,我使用的是mongoid,所以没有任何为我提供了很多关系:|@adrianthedev,请看我上面的更新。是的@matiss。我就是这么做的。这不是rails/AR/relationships的方式,但对我来说可以。现在我有了这个桥接模型通道
,每个通道都有不同的模型(因此我不会使通道
模型过载)。我遗憾的是没有关系问题。除非我将url
(或查询时可能需要的任何其他属性)属性存储到频道
模型中(可能会过载),否则我无法在不知道它是哪种频道的情况下执行当前用户.channels.where(url:'google.com')
class Channel < ApplicationRecord
scope :facebook_channels, -> { where(channel_type: "facebook") }
end