【问题标题】:Making sure associated column is unique确保关联列是唯一的
【发布时间】:2018-12-03 09:41:05
【问题描述】:

问题:我想确保一列是唯一的,如果发生更新/创建,它不会创建新行,而只会编辑现有行。

更集中的问题:我有一个条带帐户表,该表以前使用以下代码与用户相关联:

stripe_account.rb(模型)

  belongs_to :user, optional: true

  has_one :bank_account

  validates :user_id, presence: true, uniqueness: true

这行得通。

虽然,我最近添加了一个新的设计模型,Affiliates,它是它自己的模型和表和“has_many :users”.. 它将用于将附属帐户附加到用户,所以当用户销售产品,他们会通过条纹获得会员佣金。

现在,我在测试为联属会员创建条带帐户时遇到了一个问题(现在用户也会遇到同样的问题)。

我有这个模型:

belongs_to :user, optional: true

  belongs_to :affiliate, optional: true

  has_one :bank_account

  validates :user_id, presence: true, uniqueness: true

  validates :affiliate_id, presence: true, uniqueness: true

问题是,“验证” - 如果我使用 current_affiliate 登录,我需要注释掉 user_id 才能正常工作,反之亦然。

当我将它们完全拿走时,表格会创建一个新行。现在它确实删除了 stripe_account 表中的“affiliate_id”或“user_id”参数,但它保留了该行,这意味着它创建了一个新的 stripe_account ID - 这很不方便。我需要它来简单地覆盖用户已经关联的当前 ID(行),就像我添加新的 Devise 模型之前它的工作方式一样。

如何才能使编辑/更新仅覆盖已与登录用户或附属 ID 关联的当前行而不创建新行?

【问题讨论】:

  • 我认为你需要自己处理这个问题,因为 Rails 做不到。
  • 在您的关联定义中,为什么指定它们是可选的,只是为了通过验证来验证它们的存在? Rails 5 默认验证 belongs_to 关联的存在。另外,对不起,如果这很愚蠢,我不是以英语为母语的人,但是如果可以将会员帐户附加到用户,这是否意味着用户可以拥有许多会员,而不是相反?
  • @emaillenin 你到底是什么意思?在我添加附属设计模型之前它正在工作。没有办法根据谁登录来验证?
  • @StefanRendevski 是的,我认为你是对的。我希望用户有 1 个会员,但会员可以分配给许多用户...我目前的模型设置如下:(在affiliate.rb 模型中)= has_many :users ...(在 users.rb 模型中)belongs_to :affiliate .... 这不对吗?
  • --- 然后我在 users 表中有affiliate_id

标签: ruby-on-rails ruby


【解决方案1】:

更新记录时需要这样做。验证是为了确保不允许同一用户拥有多个 StripeAccount,但您必须做到这一点。因此,要更新记录或创建新记录(如果它不存在),您可以使用find_or_create_by 并通过useruser_id 查找,类似于(我不确切知道您要更新的字段) :

StripeAccount.find_or_create_by(user: user) do |stripe_account|
  stripe_account.bank = bank
  stripe_account.money = 20
end

顺便说一句,在您的验证中,您可能想要验证 user 的存在而不是 user_id,因为这不仅可以确保设置了字段 user_id,而且还可以确保有一个用户使用该字段编号:

validates :user, presence: true, uniqueness: true

【讨论】:

  • 如果您想在以会员身份登录时找到条带帐户,则需要StripeAccount.where(user: user).or(StripeAccount.where(affiliate: affiliate)),如果它不存在,则创建它。
  • @Ana Maria,我认为这可能是正确的方法。因为在更新方法中的 stripeaccount 控制器中,我有类似“begin @.stripe_account = StripeAccount.new(stripe_account_params)”之类的东西——但我考虑到了这一点,对我来说最好实际保留数据作为记录- 至少大概 90 天左右
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-28
  • 2017-11-13
  • 2021-12-08
相关资源
最近更新 更多