Rails 请教大家关于多条件查询这种场景,应该按照什么思路去做

shaunli · 2015年03月19日 · 最后由 nomadop 回复于 2015年04月08日 · 3606 次阅读

多条件联动查询,就是下面这种效果

昨天加今天查了很多相关资料,下面是我的想法:

1. 由 js 在前端收集当前的筛选条件 给每个查询条件绑定 click 事件,点击则添加一个 class 标记(selected),再次点击取消这个标记

2. 当触发查询时,将收集的筛选条件以 json 格式向后端发送 ajax 请求 用 js 找到所有带有 selected 标记的元素,得到全部筛选条件,然后构造 json,发 ajax 请求

3. 对应控制器方法处理该请求,提取筛选条件,构造查询条件,向模型发起查询 从 params 参数中提取出筛选条件,简单整理一下,然后用 ActiveRecord 查询(刚开始研究这一块,具体怎么做还不清楚)

4. 模型返回查询结果给控制器

5. 控制器将查询结果打包成 json 串,以 ajax 回调的方式发回前端

6. 前端 js 动态修改页面,展示查询结果

这个想法应该是能做(现在我已经把 1、2、5、6 都跑通了,正在研究 3、4),但是我总觉得不太好,太麻烦,想听听有经验的大牛们是如何实现这种业务的。😮

这不是典型的 angularjs 场景吗?

1, 2, 6 找个能做 2-way binding 的库就能直接做了。如果你商品不多,其实一次全读进前端,纯用 JS 筛更快。商品数量太多就不行了。我觉得 3k 多个也许问题不大...

类似的 http://nongmin365.com/items/30721968185540671 我是构造条件到 url 根据 url 做 query

一般都是 url 后面跟一个参数,而参数的组成,有很多种,一种是用位置对应类似 LS 的,依照截图来说,比如出版社的排第一,那你参数的第一位的数字就是代表选择了哪个出版社!query=03010401 代表 scholastic,平装,1 星以上,3-5 折,哪一项没选就用 0 表示

#1 楼 @est 没研究过 AngularJS,以后有机会研究一下吧,目前要做的东西涉及到查询的也就这一个地方,凑合弄出来就行

#2 楼 @blacktulip 商品数一共 5k 多吧,不方便一次全读进前端,移动设备可能比较吃力。另外能不能说一下 2-way binding 的库该怎么做呢?谢谢😄

#3 楼 @huobazi 对对对,想弄成你这种。我现在是用 post 传 query 条件,现在还不知道具体该怎么查询。

#4 楼 @stephen 哦,明白了。不过我想做的查询条件需要支持多选,用参数化 url 做会不会太麻烦了?

#7 楼 @shaunli 用 post 还是 get 都不影响查询啊 有哪个条件就把哪个条件放 where 里去查

#9 楼 @huobazi 嗯,正在自学查询这部分的资料😊

#8 楼 @shaunli 多选的话就要用到 or 断言,可以用 Rails 自带的 arel 组件实现。示例代码:

products = Product.arel_table

Product.where(products[:publishing_house].eq('人民邮电出版社').or(products[:publishing_house].eq('清华大学出版社')))

呃,这种写法有点长呢,可以用 inject(:or) 拼接断言呢,比如这种写法: https://github.com/spree/spree/blob/master/core/app/models/spree/product.rb#L157-L163

def self.like_any(fields, values)
  where fields.map { |field|
    values.map { |value|
      arel_table[field].matches("%#{value}%")
    }.inject(:or)
  }.inject(:or)
end

Spree 中的这段代码用于查询产品,fields 是需要匹配的字段,values 是选中的值。

#8 楼 @shaunli 多选的话就要用到 or 断言,可以用 Rails 自带的 arel 组件实现。示例代码:

products = Product.arel_table

Product.where(products[:publishing_house].eq('人民邮电出版社').or(products[:publishing_house].eq('清华大学出版社')))

呃,这种写法有点长呢,可以用 inject(:or) 拼接断言呢,比如这种写法: https://github.com/spree/spree/blob/master/core/app/models/spree/product.rb#L157-L163

def self.like_any(fields, values)
  where fields.map { |field|
    values.map { |value|
      arel_table[field].matches("%#{value}%")
    }.inject(:or)
  }.inject(:or)
end

Spree 中的这段代码用于查询产品,fields 是需要匹配的字段,values 是选中的值。

#11 楼 @Martin91 太感谢了👍 我试试

#12 楼 @Martin91 这样写可以吗?

Product.where(publishing_house: ['人民邮电出版社', '清华大学出版社'])

#14 楼 @nomadop 这样可以,会更简短,我提的那种更底层,更灵活,适合多字段 or 查询。

#15 楼 @Martin91 懂了,那样写虽然会更简洁,但无法支持多字段 or. 添加多字段的话实际上字段间是 and, 受教了。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号