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