我有一个useLines
表,其中有一个工作地址和一个家庭地址。如果这些个人资料的用户在一起住,则多个个人资料可以共享相同的家庭住址(如果他们一起工作,则可以共享工作地址)。我可以通过哪些方式实现这一目标?我认为flat
在这种情况下会起作用,但是我想不出一种实现此方法的方法。
理想情况下,我希望能够执行类似Profile
或has_many :through
我在寻找一些答案时看到了这个线程: Order having multiple addresses of different kinds
方法1和2似乎不适用于我的情况,因为外键位于Profile.home_address
表中,这将使一个地址仅绑定到一个Profile.addresses.where(address_type: "home")
。方法3可行,但我只是想知道是否还有另一种方法可以做到。拥有Address
和Profile
似乎表明我拥有home_address_id
和work_address_id
模型。
答案 0 :(得分:2)
首先,您可能希望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
现在,您可以执行@profile.addresses
。如果您希望能够执行@profile.home_address
(而不是Profile.home_address
,因为您想在实例而非类上调用该方法),则可以执行以下操作:
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
与address
碰巧有多个address_type: 'home'
,则.first
可能会也可能不会产生意外结果。
如果您有:
class User < ActiveRecord::Base
has_one :profile
delegate :home_address, to: :profile
end
然后您可以进行@user.home_address
。
答案 1 :(得分:2)
假设以下情况:
最后我得到了一种简单的方法:
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