0

has_many :through我正在尝试使用 UserLocations 连接表在 User 模型和 Location 模型之间实现双向关联。这将启用使用内置 ActiveRecord 方法设置用户位置,即。@user.locations = [<Location 1>, <Location 2>, ...]. 我的目标是不将位置与用户单独关联,而是让用户通过另一个字段一次或多个添加和删除它们::zip_code. 这意味着当用户添加邮政编码时,ActiveRecord 应该将一条记录插入到 UserLocations 中(类似于INSERT INTO user_locations (user_id, zip_code) VALUES (1, 12345))。然后,当@user.locations被调用时,ActiveRecord 应该加入:zip_code并获取匹配的位置。我当前的实现有效,除了INSERT为与邮政编码关联的每个位置生成一个 UserLocations 。

class User < ActiveRecord::Base
  has_many :user_locations
  has_many :locations, through: :user_locations
end

class UserLocation < ActiveRecord::Base
  belongs_to :user
  belongs_to :location, primary_key: :zip_code, foreign_key: :zip_code
end

class Location < ActiveRecord::Base
  has_many :user_locations, primary_key: :zip_code, foreign_key: :zip_code
  has_many :users, through: :user_locations
end

我尝试过的事情:

  • validates_uniqueness_of :zip_code, scope: :user_id- 只是抛出一个验证错误并阻止所有记录创建
  • has_many unique: true- 不会阻止重复的数据库查询
  • add_index unique: truefor (user_id, zip_code)- 至少可以防止创建重复条目,但我试图完全防止不必要的查询

使用像这样的问题作为指导并没有让我更接近。如果不使用我自己的方法来获取/设置用户位置,我正在尝试做的事情是否可行?

4

3 回答 3

0

看起来您的关联设置正确。

当您在 Rails 中有has_many关联并想要执行以下操作时:

@user.locations = [<Location 1>, <Location 2>, ...]

Rails 将为INSERT数组中的每个位置创建单独的语句,尽管它会为您执行大量操作DELETE。如果您希望它执行批量INSERT语句,则需要滚动您自己的代码或查看activerecord-import gem来执行此操作。

至于重复项,如果您只执行上述代码,则不应出现重复记录错误,除非该位置数组中有重复项,在这种情况下您应该uniq先调用它。

于 2013-08-02T10:18:41.693 回答
0

如果我错了就阻止我:)

您的locations表中有邮政编码(即:111、222、333) 当用户为自己选择邮政编码“111”时,他的记录与现有locations记录相关联;但是当用户选择邮政编码“444”时,locations会创建一条新记录并链接到该用户。选择“444”的下一次使用将链接到同一记录。

如果我的假设正确,你应该有:

  • validates_uniqueness_of :zip_code(无范围)在您的Location模型中
  • 在您的User模型中创建/更新您可以使用Location.find_or_create_by(params[:zipcode])

这是伪代码(不要复制粘贴),我不完全知道您的代码是如何编写的,但我的意思是让您看看find_or_create,我相信这可能是您的解决方案

于 2013-08-01T00:42:17.487 回答
0

首先,我在 Rails 方面还不是很有经验,但我仍然会尽力提供帮助:)

我要做的不是使用邮政编码作为密钥。当用户输入邮政编码时,您在 Location 中查找代码:

@zip_code = Location.where(zipcode: user_input).first
@zip_code.user_locations.create!(user_id #some other stuff you want)

这样,您将位置的 id 存储到用户位置中,并且不会重复。然后,您可以通过加入 UserLocation 和 Location 来生成用户位置。

但正如我所说,由于我是初学者,可能有更好的方法来做到这一点。

于 2013-07-31T23:04:35.683 回答