使用Rails中的输入编号选择带有范围的对象

时间:2017-04-28 14:15:52

标签: sql ruby-on-rails ruby postgresql ruby-on-rails-5

我的对象具有最小/最大年龄范围:

name: "Event 1"
type: Package # inheritance
min_age: 1
max_age: 8
category_id: 2 # Birthday

我想通过查看对象的年龄范围是否满足输入的数字,根据用户对年龄和类型的偏好选择并返回这些对象。

目前我很困惑:

控制器代码:

age = params[:age]
item_type = params[:item_type]
@all_items = Item.where("categories.name = ?", 'birthday')
@events = @all_items.where("(type: #{item_type}) AND ...here I need to lookup if the #{age} variable is within the object range")

现在的问题是我需要通过输入的用户号码选择一个生日事件,在对象本身上有Range。有没有办法在不经过每一个对象的情况下做到这一点?

1 个答案:

答案 0 :(得分:3)

@events = @all_items.where("type = #{item_type} AND min_age >= #{age} AND max_age <= #{age}")

我认为这些关联看起来如下:

Item has_many :categories
Category belongs_to :item

在这种情况下

Item.where("categories.name = ?", 'birthday')

很可能会失败,因为categories没有像

那样加入
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR:  missing FROM-clause entry for table "categories"

以下是您想要做的事情:

Item.joins(:categories)
    .where(categories: { name: 'birthday' })
    .where("items.type = '#{item_type}' AND items.min_age >= #{age} AND items.max_age <= #{age}")
    .group('items.id')

使用PostgreSQL's BETWEEN可能会使查询看起来更好更短:

Item.joins(:categories)
    .where(categories: { name: 'birthday' })
    .where("items.type = '#{item_type}' AND #{age} BETWEEN items.min_age AND items.max_age")
    .group('items.id')