有没有办法在活动记录中制作模型方法?

Is there a way to make a model method in active record?

我正在考虑创建一个方法来给我 Active::Record::Associations::CollectionProxy 中的特定对象。

例如,我有一个用户模型,其中包含许多 user_checklists 和 user_checklists belongs_to 清单模型。所以我想创建一个方法来检查清单模型中的值和 return 来自 user_checklist 模型的值。

例如。 清单 table 有以下行

╔═════════════════════╦══════════════════╗
║         id          ║    name          ║
╠═════════════════════╬══════════════════╣
║          1          ║ Complete MBA     ║
╠═════════════════════╬══════════════════╣
║          2          ║ Painting class   ║
╚═════════════════════╩══════════════════╝

并且用户 table 具有以下

╔═════════════════════╦══════════════════╗
║         id          ║    name          ║
╠═════════════════════╬══════════════════╣
║          1          ║    name          ║
╚═════════════════════╩══════════════════╝

和user_checklist有下面一行

╔════════════╦════════════╦═══════════════╦═══════════════╗
║    id      ║    user_id ║ checklist_id  ║   completed   ║
╠════════════╬════════════╬═══════════════╬═══════════════╣
║     1      ║      1     ║      1        ║     true      ║
╠════════════╬════════════╬═══════════════╬═══════════════╣
║     2      ║      1     ║      2        ║     false     ║
╚════════════╩════════════╩═══════════════╩═══════════════╝

所以我想在 user_checklist 中制作一个名为 MBA 的方法,它将给我 MBA 完成值。

这就是我想要的调用方式 user.first.user_checklists.mba.completed

我不知道如何实现。还是我的想法完全错了?

所以我想出了一个办法。在 user_checklists 上创建范围,仅查找 mba_id 和 returns 的值形式 user_checkilust

scope :mba, -> { where(checklist_id: Checklist.where(name: "Completed MBA").first&.id) }

在那之后我可以做到

User.first.user_checklists.mba.first&.completed

所以这对我现在有用。

我建议只选择清单的 ID。

scope :mba, -> { where(checklist_id: Checklist.where(name: "Completed MBA").pluck(:id) }

将从数据库中仅查询所需的列 (id)(具有更好的性能),

 SELECT "checklists"."id" FROM "checklists" WHERE "checklists"."id" = 

你可以得到和你一样的东西

User.first.user_checklists.mba.first&.completed

您可以更新范围以避免 N+1 查询:

scope :mba, -> { joins(:checklists).where('checklists.name = "Completed MBA"')

您不需要 select 作用域中的第一个和 id,因为我猜您会在下一个请求中调用 first 方法:

User.first.user_checklists.mba.first&.completed