包含相关元素

时间:2017-11-08 14:41:25

标签: ruby-on-rails ruby

我想将include方法与我的帖子的相关元素一起使用

我的帖子可以与不同类型的元素相关联。而且我使用了一个值:cat知道女巫元素的关联。

这个值有效(cat:(1 =>消息,2 =>问题,3 =>任务,4 =>事件)与关联has_one

示例:如果post.cat == 3,我可以调用与post.task方法相关的任务

现在,我想用方法include来优化我的Post / Index的SQL请求。但暂时不工作。你能帮我找到我的代码错误吗?

Post_controller:

def index
  @posts = current_user.posts
  @posts.each do |post|
    if post.cat == 3
      @task = post.task.includes(:users)
    elsif post.cat ==  4
      @event = post.event.includes(:reminds)
    end
  end
end

错误:未定义的方法`includes'

编辑:

Post_model:

class Post < ApplicationRecord
  has_one :post_message, dependent: :destroy
  has_one :question, dependent: :destroy
  has_one :task, dependent: :destroy
  has_one :event, dependent: :destroy
end

Task_model:

class Task < ApplicationRecord
  belongs_to :post
  has_many :users_task, dependent: :destroy
  has_many :users, through: :users_task
end

3 个答案:

答案 0 :(得分:2)

你为什么使用@ posts.each?

对我来说,最好的解决方案是找到定义的cat的所有帖子来运行includes方法。在你的情况下,它会是这样的:

/g:"anything in this file"

答案 1 :(得分:2)

好吧,经过多次尝试,我选择了一个范围方法来运行include方法。它不是一个非常优雅的解决方案,但我认为它在我的情况下是最好的。

所以我在Post_Model中准备了范围:

scope :with_tasks, -> { where(cat: 3).includes(:user).includes(task: :users) }
scope :with_events, -> { where(cat: 4).includes(:user).includes(event: :reminds) }

然后,我在我的索引动作中渲染它们:

@posts = current_user.posts.with_tasks + current_user.posts.with_events

因此代码生成2个SQL请求以查找帖子(每个类别一个)。

我认为有一种方法可以将所有这些直接加入到新的全球范围内,但我不知道如何。所以,如果有人知道,他可以编辑答案

享受!

答案 2 :(得分:-1)

如果您收到undefined method: 'includes'错误,则表示post.taskpost.event没有像您的代码所期望的那样返回ActiveRecord对象。您确定在执行该点时始终会为.task.event设置值吗?是否存在该值可能为nil或空白的情况?

顺便问一下,你听说过'polymorphic associations'吗?将关联定义为多态允许您将任意类型的记录与特定列相关联(通过在幕后的每个记录中存储对象ID和类名)。看起来这与您的用例完全匹配。使用内置机制比尝试根据代码中的类别进行所有if-then切换要容易得多。