1、介绍
- 当我们要筛选不同数据的时候,会出现一种情况大量的
if
,unless
,switch
代码做判断条件。 - 所以我们可以使用
Rails ApplicationRecord
类的scope
,他可以把常用的对象封装在一个方法里面,这里借用一段Rails guide
的代码
class Order < ApplicationRecord
scope :created_before, ->(time) { where("created_at < ?", time) if time.present? }
end
解释:上面代码不管是true
还是false
,最终结果都是返回ActiveRecord::Relation
对象,where
也是ActiveRecord::Relation
对象。
注意:if time.present?
如果是false,那么他返回的是nil,因此它也会返回ActiveRecord::Relation
对象,但是如果调用的方法不是ActiveRecord::Relation
对象,它就会引发 NoMethodError 异常。
2、优雅的使用scope
- 经过上面的介绍我们现在来优雅的使用它
例子:
# controller
class ArticlesController < ApplicationController
def index
# 即使某个参数为空,语句也能正常执行
@articles = Article.name_condition(params[:name])
.phone_condition(params[:photo])
end
end
# model
class Article < ApplicationRecord
scope :name_condition, ->(name) do
where('name = ?', name) if name.present?
end
scope :phone_condition, ->(phone) do
where("lower(phone) like ?", "%#{phone}%") if phone.present?
end
end
解释:上面代码就算参数是空,语句也会正常执行啦,以后所有参数判断都在scope
,也可以配合gem grape
的params
参数验证,这样可以省去你判断参数是否合法的问题。
提醒:其实scope
在很多框架都有提供,像php laravel
和golang gorm
也可以使用上面这种方法。
golang gorm的使用方法:
// 编写 scope
func LocationLatitude(latitude string) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
if latitude != "" {
return db.Where("latitude = ?", latitude)
}
return db
}
}
// 使用 scope
func (location Location) FindByCriteria(l Location) (respLocations []Location, err error) {
result := db.DB.Scopes(LocationName(l.Name),
LocationStatus(l.Status),
LocationType(l.LocationType),
LocationLatitude(l.Latitude),
LocationLongitude(l.Longitude)).Find(&respLocations)
return respLocations, result.Error
}
结束语:抱歉啊! 作者很久没做php
开发了,laravel
的使用代码我目前没有嘿嘿,本篇分享结束啦。。