建立搜索用gem 'ransack'
不好吗? 完整又便利。
真的.....但是有些小东西,自己刻一个出来,还是蛮好玩的。
简单复习一下。
Model
里的scope也是新手常会被问的内容,毕竟对程序码维护及重构还是有所帮助,所以稍微复习一下。
当商业逻辑是简单搜索条件时,多用scope
。
当商业逻辑有复杂运算时,使用类别方法
。
第一个Model
建立时,可能其相对应的controller
会直接打上。
def index
@roles = Role.all
end
随着开发,可能index
需要不同的排列方式,可能希望只有包含特定资料。
def index
@roles = Role.order(id: :desc)
end
def some_action
@roles = Role.where('address LIKE ?', "%屏东%")
end
需求越来越多时,查询语句也就越来越长。
def some_action
@roles = Role.where('address LIKE ? OR phone_number LIKE ?', "%屏东%", "%878%").order(id: :desc)
end
scope
这个方法可以让你的controller
变乾净(DRY)。
可以直接在Model
。
class Role
scope :scope_name_you_like, -> {where('address LIKE ?', "%屏东%")}
end
controller
就可以改写。
def some_action
@roles = Role.scope_name_you_like
end
还记得lambda
吗? 就是它。
D-26.Block、Proc、lambda https://ithelp.ithome.com.tw/articles/10260028
所以如果有需求,也可以带参数。例如
class Role
scope :whos_pay__high, ->(100000) { where["Pay > ?", 100000] }
end
等等搜索功能就是会利用到带参数
scope
与scope
之间是可以连在一起使用的。
为你自己学Ruby on Rails
class Product < ApplicationRecord
scope :available, -> { price_over(0).where(is_available: true) }
scope :price_over, ->(p) { where(["price > ?", p]) }
end
建立scope
不要为了单一搜索。例如
scope :first_pingtung_role, -> { where('address LIKE ?', "%屏东%").first }
有需求单独show
可以这样处理。
class Role
scope :pingtung_role, -> { where('address LIKE ?', "%屏东%") }
end
# controler
def some_show
@role = Role.pingtung_role.first
end
保有原本的scope :pingtung_role
,也可以重复利用。
scope
建立简单搜索功能。简单的搜索功能至少要有一个简单的搜索框。
view
。
<%= form_tag roles_path, method: :get do %>
<%= text_field_tag :search, params[:search], placeholder: "请输入" %>
<%= submit_tag "送出", name: nil %>
<% end %>
modle
class Role
# 这一个是原本给index用的。
scope :by_last_name, -> { order(:last_name) }
# 这一个是搜索功能的。
scope :any_name_you_want, -> (search) { where('address LIKE ?', "%#{search}%") if search.present?}
end
记得两个%%
喔,没有会变成,address
一定要 == #{search}。
controller
def index
begin params[:search]
@roles = Role.any_name_you_want(params[:search])
rescue
@roles = Role.by_last_name
end
end
这样就完成了一个关於地址的简单搜索,也可以稍稍加工,让这个搜索对另一个栏位也有反应。
class Role
scope :any_name_you_want, -> (search) { where('address LIKE ? OR first_name LIKE ?', "%#{search}%", "%#{search}%") if search.present?}
end
将scope
与render
还有callback
一起运用,可以再让code整洁一点。
可能view
除了index
,还会需要再多一些页面是跟关联性有关,或是有某些特定资料的。
例如:
def index
begin params[:search]
@roles = Role.any_name_you_want(params[:search])
rescue
@roles = Role.by_last_name
end
end
def phone_number
@roles = Role.order(:phone_number)
end
def job
@roles = Role.order(:job)
end
但是这三页可能长得都一样,那就不如直接将原本的index.html.erb
改为_index.html.erb
,将这三页都render
上去。
例如:
index.html.erb
<% render 'index'%>
phone_numbe.html.erb
<% render 'index'%>
job.html.erb
<% render 'index'%>
这时我们再将controller
修改一下。
before_action :roles_list, only: [:index, :phone_number, :job]
def index
end
def phone_numbe
end
def job
end
private
def roles_list
@roles = case action_name
when "phone_number"
Role.order(:phone_number)
when "job"
Role.order(:job)
else
Role.by_last_name
end.any_name_you_want(params[:search])
end
这三页除了初始会看到的资料不同,但搜索功能一样可以共用。
这样利用scope
客制化搜索方法,简单又兼顾code
整洁的搜索功能就完成啦。
>>: Day 9:AWS是什麽?30天从动漫/影视作品看AWS服务应用 -《PSYCHO-PASS心灵判官》part 3
今日kata 原始题目如下:(4kyu) Write a function validSolutio...
前言 今天加权指数开低,维持一个大跌,来观察讯号灯和大盘、个股的关系,来验证我们的讯号灯能不能参考。...
在写app时常常会因为所有app在外观看起来一样,所以往往会要找很久才能找到自己想要执行的app,所...
Event Flow 事件流 DOM的Event flow概念,指的是「网页元素接收事件的顺序」。 ...
前面我们讲了一些参数的属性,我们可以通过 validateSet 来限制参数值的范围。但有些情况下,...