簡體   English   中英

Rails ActiveRecord查詢

[英]Rails ActiveRecord querying

所以我有以下三個模型: Assignment.rbSubmission.rbUser.rb

這里是關系:

class Assignment
  has_many :submissions
end

class Submission
  belongs_to :assignment
  belongs_to :user
  # submission has a boolean column called submitted with val true or false
end

class User
  has_many submissions
end

我想知道如何查詢用戶未提交的作業(以干凈的方式)? 如果用戶提交作業,則將創建該作業和用戶的新提交。

不知道我是否提供了足夠的信息供任何人回答,因此如果有其他需要,請發表評論。

@Norly Canarias使用的邏輯是正確的,但是我將其更改為使用User類上的方法,並且還將對其進行修改以使其與數據庫無關(例如,使用'submissions.submitted = true'不會在Postgres工作)。

class User < ApplicationRecord
  has_many :submissions
  has_many :assignments, through: :submissions

  def submitted_assignments
    assignments.where(submissions: {submitted: true})
  end

  def unsubmitted_assignments
    Assignment.where.not(id: submitted_assignments)
  end
end

我已經對此進行了測試,並且可以正常工作。 對於擁有提交了== true的分配1的提交,以及提交了== false的分配2的提交的用戶,並假設存在另外兩個沒有提交的分配(3和4),得到:

>> user.submitted_assignments.ids
#=>[1]
>> user.unsubmitted_assignments.ids
#=>[2, 3, 4]

我認為類似這樣的方法可能有效(盡管我尚未測試):

class Assignment
  has_many :submissions
end

class Submission
  belongs_to :assignment
  belongs_to :user
end

class User
  has_many :submissions
  has_many :assignments, through: :submissions
end

user         = User.first
submitted    = user.assignments.where('submissions.submitted = true')
not_submitted = Assignment.where.not(id: submitted)

您也可以使其成為范圍

class Assignment
   has_many :submissions
   scope :not_submitted_by_user, ->(user) do
     where.not(id: user.assignments.where('submissions.submitted = true'))
   end
end

user = User.first    
not_submitted = Assignment.not_submitted_by_user(user)

獲取不是來自特定用戶的所有分配

@assignments = Assignment.where.not(user_id: user_id)

一種干凈的方法是在工作分配模型中創建范圍

class Assignment
  has_many :submissions

  scope :not_from_user, ->(user_id) {where.not(user_id: user_id) }
end

然后打電話

 @assignments = Assignment.not_from_user 1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM