gpt4 book ai didi

ruby-on-rails - 查找关联记录不存在的父记录

转载 作者:搜寻专家 更新时间:2023-10-30 20:50:29 25 4
gpt4 key购买 nike

这是我所拥有的关联。

award_test.rb

has_many :instructor_student_awards , :dependent => :destroy
has_many :award_test_payment_notifications, dependent: :destroy

instructor_student.rb

has_many :instructor_student_awards, :dependent => :destroy
has_many :awards, through: :instructor_student_awards
has_many :award_test_payment_notifications, dependent: :destroy

instructor_student_award.rb

belongs_to :award
belongs_to :instructor_student
belongs_to :award_test

award_test_payment_notification.rb

belongs_to :award_test
belongs_to :instructor_student

schema.rb

"award_tests"
t.date "test_date"
t.time "test_time"
t.integer "award_id"
t.decimal "test_fee"


"award_test_payment_notifications"
t.text "response_params"
t.string "status"
t.string "transaction_id"
t.string "paid_by"
t.float "amount"
t.string "merchant_reference"
t.integer "award_test_id"
t.integer "instructor_student_id"

"instructor_student_awards"
t.integer "instructor_student_id"
t.integer "award_test_id"
t.boolean "is_registered", default: false

任何讲师学生都可以注册参加奖励测试。一名讲师学生可以注册多个奖励测试。 讲师学生必须为在奖励测试中进行测试支付费用。教师学生可以通过2种方式支付奖励测试。

  1. 在线

  2. 现金

当教师学生为该奖励测试付费时。比教师学生和 award_test 数据将插入 award_test_payment_notifications。 award_test_notifications 表包含与学生和奖励测试相关的所有字段。

如果讲师学生不为该奖励测试支付费用,那么奖励测试付款通知将仅在该奖励测试的情况下为零。

教师学生 1 注册 3 个奖励测试,如 10、11、12。

指导学生 1 为奖励测试 10 支付了现金。

教师学生 1 在线支付了奖励测试 12。

指导学生 1 没有支付奖励测试 11。

因此讲师学生有 2 个奖励测试付款通知 1) for award test 10 2) award test 12

当我在 2017 年 1 月 1 日至 2017 年 7 月 31 日期间搜索奖项测试时。这 3 个奖项属于此过滤器 比讲师学生 1 将返回 3 个类别。

  1. 现金支付

  2. 在线支付

  3. 未付

我有 2 个日期,我需要根据这 2 个日期过滤数据。该日期将是测试日期。我必须区分所有现金支付、在线支付和未支付。

以下是我为获取现金支付和在线支付所做的查询。

current_admin_award_test = AwardTest.joins(instructor_student_awards: {:instructor_student => :award_test_payment_notifications}).where("test_date <= ? AND test_date >= ? AND instructor_student_awards.instructor_student_id  IN (?) ", @endMonth.end_of_month, @startMonth.beginning_of_month, @all_instructor_student_ids)

@award_test_cash = current_admin_award_test.joins("INNER JOIN award_test_payment_notifications atn ON award_test_payment_notifications.award_test_id = award_tests.id").where("award_test_payment_notifications.paid_by = ? ","Cash").select("DISTINCT(award_tests.id), instructor_student_awards.instructor_student_id, award_test_payment_notifications.paid_by, award_tests.test_fee, award_tests.test_date")

@award_test_paid_online = current_admin_award_test.joins("INNER JOIN award_test_payment_notifications atn ON award_test_payment_notifications.award_test_id = award_tests.id").where("award_test_payment_notifications.paid_by <> ? ","Cash").select("DISTINCT(award_tests.id), instructor_student_awards.instructor_student_id, award_test_payment_notifications.paid_by, award_tests.test_fee, award_tests.test_date")

它工作正常。但我不知道如何为一名教师学生获得多次奖励测试的未付费奖励测试列表。

更新 1

what is the role of InstructorStudentAward ?

When instructor student register award test. the data logged in instructor student awards.

if any payment is logged for that AwardTest, the event is assumed to be paid-in-full. OK?

Yes. when instructor student paid for award test. award test payment notifications will be logged in not matter what is amount.

Is an InstructorStudentAward association created for every InstructorStudent that registers for an AwardTest?

Yes , you are right .

So what you want is, any InstructorStudentAward JOIN AwardTest JOIN InstructorStudent pair that is missing an associated AwardTestPaymentNotification

Yes

Can I assume you're using PostgreSQL database

Yes, I am using PostgreSQL database.

最佳答案

我在这个 github 存储库中添加了您问题中我需要的部分(以及一些您未提及的内容)以复制您的关联结构。

https://github.com/kingdonb/ashvin-stackoverflow-post

项目根目录中的

example.rb 是一个 Rails Runner 脚本,我想它大致复制了这些东西是如何创建和链接在一起的。

您的查询,重新格式化以使其更具可读性:

current_admin_award_test = AwardTest.joins(
instructor_student_awards: {
:instructor_student => :award_test_payment_notifications
}).where("test_date <= ? AND test_date >= ?
AND instructor_student_awards.instructor_student_id
IN (?) ",
@endMonth.end_of_month,
@startMonth.beginning_of_month, @all_instructor_student_ids)

@award_test_cash = current_admin_award_test.joins(
"INNER JOIN award_test_payment_notifications atn ON
award_test_payment_notifications.award_test_id =
award_tests.id").
where(
"award_test_payment_notifications.paid_by = ? ", "Cash"
).select(
"DISTINCT(award_tests.id),
instructor_student_awards.instructor_student_id,
award_test_payment_notifications.paid_by,
award_tests.test_fee, award_tests.test_date")

@award_test_paid_online = current_admin_award_test.joins(
"INNER JOIN award_test_payment_notifications atn ON
award_test_payment_notifications.award_test_id =
award_tests.id").
where(
"award_test_payment_notifications.paid_by <> ? ","Cash"
).select(
"DISTINCT(award_tests.id),
instructor_student_awards.instructor_student_id,
award_test_payment_notifications.paid_by,
award_tests.test_fee, award_tests.test_date")

我认为缺少的查询不能从 current_admin_award_test 派生,如果您打算这样做的话,因为它正在默默地进行内部连接。当您在没有其他上下文的情况下说“连接”时,Rails 会推断您指的是内部连接:https://apidock.com/rails/ActiveRecord/QueryMethods/joins#docs_body

看看这个结果:

current_admin_award_test = AwardTest.joins(
instructor_student_awards: {
:instructor_student => :award_test_payment_notifications
})

您只得到已支付的 InstructorStudentAwards!

因此它会删除没有匹配的 AwardTestPaymentNotifications 的记录,因为内部联接需要两边都匹配才能产生行结果。因此,如果您从该关联对象开始查询,它永远不会返回任何未支付的记录。

你想要:

@award_test_unpaid = AwardTest.left_outer_joins(
instructor_student_awards: {
instructor_student: :award_test_payment_notifications
}).where(award_test_payment_notifications: { id: nil } ).

[ and the rest of your criteria from current_admin_award_test ]

where("test_date <= ? AND test_date >= ?
AND instructor_student_awards.instructor_student_id
IN (?) ",
@endMonth.end_of_month,
@startMonth.beginning_of_month, @all_instructor_student_ids)

如果您使用的是旧版本的 Rails,它会变得更加复杂,因为 #left_outer_joins 仅在 Rails 5.0 中添加。

如果你想改进这一点,你可以将 current_admin_award_test 做成一个不加入 award_test_payment_notifications 的参数化范围(你已经加入那个表来制作每个派生的付款状态列表,恐怕这个加入两次,这可能就是你不得不求助于使用 DISTINCT 的原因......?还是有其他原因?)

也许他们有一个 AwardTest 的多个 AwardTestPaymentNotifications,而您不想从中取回重复的 AwardTest 记录。好的。您还可以使用这个新范围作为您的 @award_test_unpaid 的基础。

scope :current_admin_award_test, ->(
end_date, begin_date, instructor_student_list) {
joins(instructor_student_awards: :instructor_student).
where("test_date <= ? AND test_date >= ?",
end_date.end_of_month, begin_date.beginning_of_month).
where(instructor_student_awards:
{ instructor_student: instructor_student_list }
)
}

(in context 在 GitHub 项目中)我把它放在 AwardTest 模型上的提交中。

您的三个私有(private)变量也可以是作用域,具有相同的参数(将它们传递给处理日期逻辑的主作用域。)

(在给出疑问的前提下,您的模型中可能已经有了这些东西,但只是没有将它们包含在问题中,因为您不想在其中放入太多代码。)

因此,如果 InstructorStudent 没有支付任何账单,他的 AwardTest 将显示在此列表中。如果所有账单都已支付,InstructorStudent 将不会出现在此列表中。我认为这就是您想要实现的目标?

如果你想进一步推导出有未付账单的 InstructorStudent 记录列表,那么你可以给他们每人发送一封措辞强硬的电子邮件,现在它看起来像这样:

@award_test_unpaid.
map(&:instructor_student_awards).flatten.
map(&:instructor_student).
map(&:id).uniq

作为奖励,我刚刚花了一些时间在我站起来的 repo 上,充实了 rails 关联和范围,以便有一个 current_unpaid 范围可以大致满足您的需求。

scope :current_unpaid, ->(
end_date, begin_date, instructor_student_list) {
current_admin_award_test(end_date, begin_date, instructor_student_list).
left_outer_joins(:award_test_payment_notifications).
where(award_test_payment_notifications: { id: nil } )
}

2017-08-04 编辑:@ashvin 透露他使用的是 Rails 4.1,所以 .left_outer_join 将无法工作,因为它直到 Rails 5 才被添加...这个原始 SQL 将工作不过,取而代之的是:

 scope :current_unpaid, ->(
end_date, begin_date, instructor_student_list) {
current_admin_award_test(end_date, begin_date, instructor_student_list).
joins("LEFT JOIN award_test_payment_notifications
ON award_tests.id =
award_test_payment_notifications.award_test_id
AND instructor_students.id =
award_test_payment_notifications.instructor_student_id").
where(award_test_payment_notifications: { id: nil } )
}

那么你可以

AwardTest.current_unpaid(Date.today, Date.today, InstructorStudent.all.map(&:id))

并获取当月所有未付费 AwardTest 的列表!

这取决于在 AwardTest 模型上设置 has_many :award_test_payment_notifications。它还取决于我们在上面进一步定义的 current_admin_award_test 范围。使该工作生效的所有更改都在此提交中:more time on rails associations .希望这对您有所帮助!

关于ruby-on-rails - 查找关联记录不存在的父记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45251279/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com