Mysql2 ::错误:'字段列表'中的未知列'sum_hours'

时间:2016-05-09 12:39:55

标签: mysql ruby-on-rails

自从我开始学习使用Redmine插件在企业中进行一些修改(作为学生学习“生活”的方式)以来已经有将近2个月了,但这个问题是我无法在任何地方找到解决方案的

让我解释一下:

我需要通过user_id和project_id对大量时间条目进行分组(没有问题),但如果我这样做,我需要在这些组中总结小时数。

结构是这样的:

  

| ID | project_id | user_id | issue_id |小时|

此信息是使用此方法构建的:

def time_entries_for_user(user, options={})
    extra_conditions = options.delete(:conditions)
    return TimeEntry.select('*,sum(hours) as sum_hours').
      includes(self.includes).
      where(self.conditions([user], extra_conditions)).
      group('issue_id, time_entries.project_id').
      order('issues.id ASC')
end

我添加了选择,因为我需要所有列加上总和1和单独的组工作得很好,但我不能使Sum列出现。 这是此方法结果的json代码:

{"test1 / SubProyectoTest1":{"logs":[{"id":24,"project_id":4,"user_id":1,"issue_id":10,"hours":6.0,"comments":"","activity_id":8,"spent_on":"2016-05-03","tyear":2016,"tmonth":5,"tweek":18,"created_on":"2016-05-03T11:07:09.000Z","updated_on":"2016-05-03T11:07:09.000Z","sum_hours":9.0}],"users":[{"id":1,.....

有趣的是,在按项目分组的其他方法中,Sum列出现。 这个很好用:

def time_entries_for_all_users(project)
    return project.time_entries.select('*,sum(hours) as sum_hours').
    includes(self.includes).
    where(self.conditions(self.users)).
    group('issue_id,user_id')
      order('issues.id ASC')
    end


{"test1 / SubProyectoTest1":{"logs":[{"id":24,"project_id":4,"user_id":1,"issue_id":10,"hours":6.0,"comments":"","activity_id":8,"spent_on":"2016-05-03","tyear":2016,"tmonth":5,"tweek":18,"created_on":"2016-05-03T11:07:09.000Z","updated_on":"2016-05-03T11:07:09.000Z","sum_hours":9.0}],"users":[{"id":1.......

在日志中,此错误显示:

  

ActionView :: Template :: Error(未定义的方法`sum_hours'代表#)

在呈现时间条目的视图上引用此代码:

 <% when l(:field_hours) %>
<strong><%= number_with_precision(time_entry.sum_hours, :precision => @precision) %></strong>

好吧,你不能打电话给那些不存在的东西......

2º时间在StackOverflow中寻求帮助所以如果你需要更多信息,因为我忘了写它,那就去做吧。

问候并感谢。

编辑:

感谢BoraMa和Emiliano,我让它开始手动添加关系。 第一个样本的代码更改为:

    def time_entries_for_user(user, options={})
        extra_conditions = options.delete(:conditions)

        return TimeEntry.select('*,sum(hours) as sum_hours').
              includes(self.includes).
              where(self.conditions([user], extra_conditions)).
              where("time_entries.user_id",user)
              group('issue_id, time_entries.project_id').
              order('issues.id ASC')
          end
   end

虽然它只显示一个具有适当小时数的记录,但是,我尝试按iss_id进行分组,并按user_id进行分组,导致仅显示1条记录。

编辑2: 最后!!我没有意识到方法的顺序可以改变结果:/。最终代码:

  def time_entries_for_user(user, options={})
    extra_conditions = options.delete(:conditions)

    return TimeEntry.group('time_entries.project_id,time_entries.issue_id').
      select('*,sum(hours) as sum_hours').
      includes(self.includes).
      where(self.conditions([user], extra_conditions)).
      where("time_entries.user_id",user)
      order('issues.id ASC')
  end

谢谢你们!

2 个答案:

答案 0 :(得分:1)

在我的测试中,手动选择的列(在您的情况下为sum_hours)通常可以在模型上执行查询时作为“虚拟”属性访问,如您的第一个示例所示 - {{1 }} 方法。

但是,如果您尝试将自定义选择添加到记录的关联,则它似乎不起作用。然后我得到与你完全相同的错误(time_entries_for_user)。为了开始工作,我建议将第二个查询(NoMethodError)重写为表单,而不使用关联,即如下所示:

time_entries_for_all_users

请注意,我们不是在当前def time_entries_for_all_users(project) TimeEntry.select('*,sum(hours) as sum_hours'). # <- no association used here includes(self.includes). where(self.conditions(self.users)). where("time_entries.project_id", project.id). # <- the assoc. is added here instead group('issue_id,user_id') order('issues.id ASC') end 记录上调用time_entries关联,而是选择具有此项目ID的所有时间条目。这应该返回与原始查询相同的记录,但自定义列也应该正常工作。您可能需要进一步更新查询,以便您的其他条件和包含也可以正常工作。

作为第二个选项,您始终可以与手动选择一起定义关联:

project

然后,您的自定义列通常可以使用以下新关联访问:

has_many :time_entries_with_hours_sum,  
         -> { select("time_entries.*, sum(hours) as sum_hours") }, class_name: "TimeEntry"

答案 1 :(得分:0)

问题是,当您以这种方式添加SUM列并转换为json时,您将没有问题,但是如果您尝试将该字段作为属性访问,则Rails将无法找到它,因为它不是该模型的一部分。

要么在视图中将json对象转换为json,要么只针对这种情况创建一个不同的方法并仅检索总和(可能使用ActiveRecord的特定 sum 方法 - 为了可读性的缘故) )。