【问题标题】:rails active record has_many foreign key after custom function自定义函数后的rails活动记录has_many外键
【发布时间】:2016-08-30 20:04:15
【问题描述】:

考虑以下模型

class User < AR
   has_many :resources
end

class Resource < AR
   belongs_to :user
end 

我有一个要求,在外键上应用一些功能后保存它。所以resources表中user_id的值与users表中的id不匹配,但可以从id重新计算。

如何定义关联?假设这个函数是 dummy_func()。

【问题讨论】:

  • 您可能应该将针对每个用户的散列 ID 保存在新列 hashed_id 中,并使用该键与 Resource 进行关系引用
  • 目标是没有人应该能够通过查看 db 将资源链接回用户

标签: ruby-on-rails activerecord associations has-many


【解决方案1】:

由于belongs_to返回的是类实例而不是关联,你可以在Resource类中定义方法

class Resource < ApplicationRecord
  def user
    User.find(user_id)
  end

  def user=(user)
    user_id = user.id
  end
end

has_many 类似的结果用户可以通过在resources 方法中创建公共关系来实现

class User < ApplicationRecord
  def resources
    Resource.where(user_id: id)
  end
end

因此,如果您使用此代码,您可以替换 Resource 模型中的任何 id,并且行为将与 belongs_to 中的完全相同(可能在深度上有一些差异)。您可以通过自己编写方法在User 模型中实现非常相似的行为。

【讨论】:

  • 有趣...它将如何影响应用程序的性能?谢谢你的回复:)
  • @sadaf 在 Resource user= 方法中只需将 id 分配给 user_id 并让 save 方法负责更新。这将为您节省更新查询。也不要忘记在资源表的 user_id 列上添加索引。然后你可以在性能方面放松一下
  • @sadaf,此示例不应降低性能。 get 方法的工作原理与 ActiveRecord 关系非常相似,所以你不应该害怕。还要感谢 Dinesh 的建议。
【解决方案2】:

也许您可以使用回调来在保存之前以某种方式修改当前的 user_id:callbacks

我会建议类似 :before_save 或类似性质的东西,您可以在其中定义您希望如何在资源表中修改 user_id,然后也有办法对其进行解密。

也许您可以使用加密 gem 来加密和解密您的属性,例如 attr-encrypted

希望这会有所帮助!

【讨论】:

  • 保存不是问题。问题是我希望关联与普通(未加密)外键一样工作。
  • 我想我不明白你的问题,也许如果你更清楚一点?您在对其应用某些功能后保存了 user_id,所以它在将其保存到表之前更改了 user_id?您希望能够获取它但让它回到原来的状态?既然如此,为什么你在尝试获取记录时不使用某种解密方法?
【解决方案3】:

在 User 模型中,您可以覆盖 setter。如果要对用户ID进行加解密(使用attr_encrypted)...

你可以试试这样的:

attr_encrypted :id, key: ENCRYPTION_KEYS[:value]

def id=(value)
  send("encrypted_value=", encrypt(:id, value))
  instance_variable_set(:@id, value)
end

然后你可以做一个解密ID的方法

def decrypted_id
  decrypt(:id, encrypted_value)
end

现在,当创建用户时,数据库将照常设置 ID。但它也会创建一个 encrypted_value,将 id 存储为加密 ID。您可以在您的应用程序周围使用此加密值,以使数据库 ID 对界面保密。

这是控制台中的示例...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-27
    相关资源
    最近更新 更多