Ruby on rails 具有不同类型地址的配置文件和2个配置文件可能共享同一地址
我有一个Ruby on rails 具有不同类型地址的配置文件和2个配置文件可能共享同一地址,ruby-on-rails,associations,Ruby On Rails,Associations,我有一个Profile表,其中有一个工作地址和一个家庭地址。如果多个配置文件的用户住在一起,则多个配置文件可以共享同一个家庭地址(如果他们一起工作,则多个配置文件可以共享工作地址)。我有什么方法可以做到这一点?我认为有很多:在这种情况下,通过可以工作,但我想不出一种方法来实现这一点 理想情况下,我希望能够像Profile.home\u address或Profile.addresses.where(地址类型:“home”) 我在寻找答案时看到了这条线索: 方法1和2似乎不适用于我的案例,因为外
Profile
表,其中有一个工作地址和一个家庭地址。如果多个配置文件的用户住在一起,则多个配置文件可以共享同一个家庭地址(如果他们一起工作,则多个配置文件可以共享工作地址)。我有什么方法可以做到这一点?我认为有很多:在这种情况下,通过可以工作,但我想不出一种方法来实现这一点
理想情况下,我希望能够像Profile.home\u address
或Profile.addresses.where(地址类型:“home”)
我在寻找答案时看到了这条线索:
方法1和2似乎不适用于我的案例,因为外键位于地址
表中,这将允许地址仅绑定到一个配置文件
。方法3会起作用,但我只是想知道是否有其他方法可以做到这一点。拥有home\u-address\u-id
和work\u-id
似乎意味着我拥有home-address
和WorkAddress
模型。首先,你可能希望Profile
和address
有一个m:m关系。这可能看起来像:
class Profile < ActiveRecord::Base
has_many :profile_addresses
has_many :addresses, through: :profile_addresses
belongs_to :user
end
class Address < ActiveRecord::Base
has_many :profile_addresses
has_many :profiles, through: :profile_addresses
end
class ProfileAddress < ActiveRecord::Base
belongs_to :profile
belongs_to :address
end
class Profile < ActiveRecord::Base
has_many :profile_addresses
has_many :addresses, through: :profile_addresses
belongs_to :user
def home_address
addresses.where(address_type: 'home').first
end
end
注意:如果@profile
碰巧有多个地址
,并且地址类型为“home”
,则。首先可能会或可能不会产生意外结果
如果您有:
class User < ActiveRecord::Base
has_one :profile
delegate :home_address, to: :profile
end
class用户
然后您可以执行@user.home\u address
假设以下情况:
- 配置文件可以有多个地址,但每种类型只有一个地址,即“家”、“工作”等
- 一个地址可以与多个档案关联,以防人们住在同一所房子里或在同一个办公室工作
- 一个地址可以是一个配置文件(用户)的“家庭”地址,而同一地址可以是另一个配置文件(用户)的“工作”地址(这是可能的,不是吗?)
我最终采用了一种简单的方法,如下所示:
class Profile
has_many :profile_addresses
def home_address
profile_addresses.where(tag: 'home').first&.address
end
def work_address
profile_addresses.where(tag: 'work').first&.address
end
end
class ProfileAddress
# field :tag
belongs_to :profile
belongs_to :address
end
class Address
end
现在让我们创建并访问一些记录:
profile_1 = Profile.find(1)
address_1 = Address.create(
street: '22-Block',
region: 'Connaught Place',
city: 'New Delhi',
state: 'Delhi',
country: 'IN'
)
# Say, `profile_1` has above `address_1` as its home address
profile_1.profile_addresses.create(tag: 'home', address: address_1)
address_2 = Address.create(
street: 'Street-43',
region: 'Raja Garden',
city: 'Mohali',
state: 'Punjab',
country: 'IN'
)
# `profile_1` has above `address_2` as its work address
profile_1.profile_addresses.create(tag: 'work', address: address_2)
# Another profile
profile_2 = Profile.find(2)
# Now, say, `profile_2` has `address_1` as its work address
profile_2.profile_addresses.create(tag: 'work', address: address_1)
# Fetching...
profile_1.home_address
=> address_1
profile_1.work_address
=> address_2
profile_2.home_address
=> nil
profile_2.work_address
=> address_1