Rails 方法:查找具有多个 where 子句的深层嵌套关联

Rails way: Finding a deeply nested association with many where clause

这似乎是一个简单的问题,但对我来说却有点困惑。我想找到一个好的方法来处理这个问题。 我有5个模型。

工作

class Job < ActiveRecord::Base
  has_many :job_entries_jobs
  has_many :job_entries, through: :job_entries_jobs
end

工作条目

class JobEntry < ActiveRecord::Base
    has_many :attachments
    has_many :job_entries_jobs
    has_many :pinned_entries, through: :job_entries_jobs
    has_many :jobs, through: :job_entries_jobs
    belongs_to :user, class_name: 'User', foreign_key: 'user_id'
end

JobEntriesJob

class JobEntriesJob < ActiveRecord::Base
  self.table_name = 'job_entries_jobs'
  has_many :pinned_entries
  belongs_to :job_entry
  belongs_to :job, touch: true
end

固定条目

class PinnedEntry < ActiveRecord::Base
  self.table_name = "pinned_entries"
  belongs_to :job_entries_job
  has_and_belongs_to_many :users
end

用户

class User < ActiveRecord::Base
  has_many :job_entries
  has_many :pinned_entries
end

我可以通过 job_iduser_id 获得 pinned_entries(job_id 和 user_id 从 request 参数获得)通过 associationsrails 的方式(我可以通过使用 SQL 获得 pinned_entries )。如果是,我应该把这个 code 放在哪里?

如果我有一个 attachment 模型怎么样

class Attachment < ActiveRecord::Base
    self.table_name = 'attachments'

    belongs_to :job_entry, :class_name => 'JobEntry', :foreign_key => 'job_entry_id'

end

而我要includeattachment(一个link和文件名)和JobEntrycontent)? 这是应该的输出

{
  "listPinnedEntries": [
    {
      "id": 1
      "user_id": 
      "text": "content of entry",
      "user": {
        "id": 
        "username": "jamesnguyen"
      },
      "attachments": [
        {
          "id": 
          "job_entry_id":
          "comment": "file name",
          "file": {
            "url": "link here"
          }
        },
        {
         "id": 
          "job_entry_id":
          "comment": "file name",
          "file": {
            "url": "link here"
          }
        }
      ]
    }]
}

感谢您的帮助

鉴于 job_iduser_id:

user = User.find(user_id)
pinned_entries = user.pinned_entries.includes(:job_entries_job).where(job_entries_jobs: {job_id: job_id})

更新(关于附件的第二个问题):

由于您正在生成值的散列,因此修改您的 PinnedEntry 模型(或者甚至可能是 @Robin 回答的 Job 模型和 User 模型)比进行脏循环更容易:

class PinnedEntry < ActiveRecord::Base
  self.table_name = "pinned_entries"
  belongs_to :job_entries_job
  belongs_to :job_entry, through: :job_entries_job
  has_many :attachments, through: :job_entry
  has_and_belongs_to_many :users
end

然后,继续我上面的第一个回答:

pinned_entries.as_json(
  only: [:id, :user_id, :text],
  include: [
    user: {
      only: [:id, :username]
    },
    attachments: {
      only: [:id, :job_entry_id, :comment]
    }
  ]
)

这将 return 一个与您想要的值相同的散列值。注意:我没有从您的附件模型中包含 file: url,没有 belongs_to :file 或可以帮助我确定附件模型与 file 和 [=18= 的关系的东西].如果它不是属性,那么我认为您必须手动将它们添加到生成的哈希中。

添加额外的 has_many to the models Job and User and link it with your PinnedEntry via the :through 可能是个好主意。

您的 Job 模型将更改为:

class Job < ActiveRecord::Base
  has_many :job_entries_jobs
  has_many :job_entries, through: :job_entries_jobs
  has_many :pinned_entries: through: :job_entries
end

然后您可以像往常一样在 Job 记录上使用 .pinned_entries。因此,您更改了 User 模型。