【问题标题】:Rails 4- lambda - joining nested modelsRails 4- lambda - 加入嵌套模型
【发布时间】:2015-08-14 09:12:30
【问题描述】:

我是 Rails 新手(通常是编码)。

我试图弄清楚如何在我的项目模型中编写一个范围,该范围基于两个属性来连接排序。

我的模特协会是:

projects has one sweep
sweep has one finalise
sweep belongs to projects
finalise belongs to sweep

在我的 project.rb 模型中,我尝试编写如下范围:

  scope :currently_available_students, lambda { joins(@sweeps.finalise).group("projects.id").merge(sweep.finalise.finished) }

在我的 finalise.rb 中,我有一个名为 :finished_at 的日期时间属性。我也有:

scope :finished, -> { where(:draft => false) }

 after_validation :set_publish_time
  def set_publish_time
    self.finalised_at = Time.now  unless self.draft
  end

我想找到已完成的项目。

在我的 projects_controller 中,我有:

  has_scope :currently_available_students

  def currently_available_students
      @projects = Project.currently_available_students
      render 'index'
  end

当我尝试这个时,我收到一条错误消息:

undefined method `finalise' for nil:NilClass

谁能看到我做错了什么?

谢谢

【问题讨论】:

    标签: ruby-on-rails lambda scope


    【解决方案1】:

    作用域实际上在类级别上起作用:

    scope :currently_available_students, lambda { joins(@sweeps.finalise).group("projects.id").merge(sweep.finalise.finished) }
    

    但是你尝试访问一个实例变量类@sweeps,它是类级别的nil

    即使joins 会被修复,它也会在稍后的合并中失败 方法,因为没有名为 sweep 的变量 - @Yury Lebedev

    【讨论】:

    • 即使joins 会被修复,但稍后在合并方法上也会失败,因为没有名为sweep 的变量
    • 嗨 - 你能看到另一种实现这一目标的方法吗?
    【解决方案2】:

    我认为你让自己的事情变得有点复杂。您无权访问范围内的任何实例变量 @sweeps,这就是您收到此错误消息的原因。

    我想你可能想写这样的东西

    scope :currently_available_students, -> { joins(sweep: :finalize).group('projects.id') }
    

    由于默认情况下连接使用内部连接,因此您只会获得具有一个或多个(在本例中为一个)finalize 的项目。

    您可以通过添加has_one :finalize, through: sweep 使其变得更加简单。然后你可以简单地写joins(:finalize).group('projects.id')。 (我从未在 has_one 关系上尝试过 through。)

    【讨论】:

    • 嗨,Albin,我尝试了这两个建议,似乎都有效,除了这个错误:PG::AmbiguousColumn: ERROR: column reference "id" is ambiguous LINE 1: ...N " finalises"."sweep_id" = "sweeps"."id" GROUP BY id ORDER ... ^ : SELECT "projects".* FROM "projects" INNER JOIN "sweeps" ON "sweeps"."project_id" = "projects" ."id" INNER JOIN "finalises" ON "finalises"."sweep_id" = "sweeps"."id" GROUP BY id ORDER BY created_at DESC
    • 哦,对不起。我会更新我的答案。您不能使用:id 的原因是多个表具有:id 列,当您加入它们并询问ID 时,没有说明数据库从哪个表抛出您所看到的错误。
    • PG::GroupingError: 错误:列“projects.id”必须出现在 GROUP BY 子句中或用于聚合函数第 1 行:选择“projects”。* FROM “projects” INNER JOIN "sweeps" ON "... ^ : SELECT "projects".* FROM "projects" INNER JOIN "sweeps" ON "sweeps"."project_id" = "projects"."id" INNER JOIN "finalises" ON "finalises" ."sweep_id" = "sweeps"."id" GROUP BY projects_id ORDER BY created_at DESC
    • 啊,postgress group BY 似乎不适用于select *。他们在这篇文章stackoverflow.com/questions/16418504/pgerror-in-group-by-clause 中有一个解决方案。但这似乎有点乏味。我会考虑一下这个问题并尝试解决问题。
    • 您应该能够同时删除group 语句,因为您使用的是has_one。或者您可以尝试使用distinct,但如果您开始链接作用域,这可能会给您带来麻烦......
    猜你喜欢
    • 2013-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多