Ruby on Rails:如果表值在指定范围之间,则返回名称

时间:2014-01-23 22:57:10

标签: ruby-on-rails ruby range

我有三个表(与此问题相关)。一个表称为组织。

我还有一个名为organization_details的表,其中包含有关组织的organization_id和多行信息。

我在事件行业工作,所以organization_details表包含一个名为total_attendance的列,其中一个人可以输入该组织出席某一年的整数。

第三个表称为分区。这总共有五行,其中列division_smallest和division_largest(指出勤范围)。每行都有一个范围来根据最近的出勤记录将组织应属于哪个部门分开。

例如,除法表中的一行显示division_smallest等于1,division_largest等于100000(再次,表示出勤)。最后,除法表还有一个名称栏(例如“Division 1”)。

我希望应用根据最近的total_attendance自动确定某个组织属于哪个部门。理想情况下,分部的名称将显示在组织索引和显示页面中。

我想为此制作一个自定义方法,但我不确定如何最好地解决它。我读了一下。之间的内容?如(可能).between?(division.division_smallest,division.division_largest)返回“#{division.name}”

...但我不确定整个方法是如何工作的,或者我是否需要完全避开它。我非常感谢对此的任何见解!

2 个答案:

答案 0 :(得分:1)

我的建议是将以下方法添加到organization.rb

def division_name
  last_details = organization_details.order('created_at DESC').first
  if last_details.present?
    Division.where(':attendance >= division_smallest AND :attendance <= division_largest', attendance: last_details.attendance).first.name
  else
    "None"
  end
end

代码首先获取最近创建的组织详细信息。如果组织有组织详细信息,则使用出勤值选择适当的部门,并返回该部门的名称。如果组织没有任何organization_details,则返回字符串“None”。您可能还希望处理出勤率不在您定义的任何部门范围内的情况。

我希望这能指出你正确的方向。

答案 1 :(得分:1)

一个天真的实现可能看起来像这样:

class Division
  def self.for_attendance(total)
    first('? BETWEEN divisions.division_smallest AND divisions.division_largest', total)
  end
end

class Organization
  def latest_division
    Division.for_attendance(organization_details.last.try(:total_attendance))
  end
end

现在呼叫some_organization.latest_division将为该组织提取最新部门。这对于“显示”页面非常有用,但是如果您拥有包含许多组织的“索引”,则会遇到麻烦 - 这两个查询需要针对每个组织运行(N + 1问题)。而是使用它:

class Division
  def self.merge_latest!(organizations)
    left_join = "LEFT JOIN organization_details od2 ON organization_details.organization_id = od2.organization_id AND organization_details.created_at < od2.created_at"
    subquery = OrganizationDetails.where(organization_id: organizations.map(&:id)).
       joins(left_join).
       where(od2: {id: nil}).to_sql
    divisions = joins("#{subquery} as t ON t.total_attendance  divisions.division_smallest AND divisions.division_largest").
                select('divisions.*, t.organization_id')
    organizations.each {|org| org.latest_division = divisions.detect{|d| d.organization_id == org.id}
  end
end

def Organization
  attr_accessor :latest_division
end

现在,您可以致电Division.merge_latest!(organizations)在单个查询中收集所有组织的最新部门,可通过组织的:latest_division属性进行寻址。