Rails Rails 定制简单的搜索

zengfengbo · 2017年06月23日 · 最后由 zengfengbo 回复于 2017年11月24日 · 1744 次阅读

Concern

# vi app/models/concerns/searchable.rb

module Searchable
extend ActiveSupport::Concern

  module ClassMethods
    def search(search, attributes: nil)
      attributes = self.new.attributes.keys - ["id", "created_at", "updated_at"] if attributes.nil?
      like_sql = attributes.map { |attr| "#{attr} LIKE ?" }.join("OR ")

      where(like_sql, *(["%#{search}%"]*attributes.size))
    end
  end

end

Model

# vi app/models/post.rb

class Post < ApplicationRecord
  include Searchable
end

Controller

# vi app/controllers/posts_controller.rb

def index
  if params[:search]
    @posts = Post.search(params[:search]).page(params[:page])
  else
    @posts = Post.page params[:page]
  end
end

View

# vi app/views/posts/index.html.erb

<%= form_tag posts_path, :method => 'get' do %>
  <p>
    <%= text_field_tag :search, params[:search] %>
    <%= submit_tag "Search", :name => nil %>
  </p>
<% end %>

这是迷你版的 ransack?

2 楼 已删除
ad583255925 回复

没用过 ransack, 就想对所有 Model 实现简单的字符串搜索。

zengfengbo 回复

推荐 ransack

if attributes.nil? 可以換成 attributes ||=

franklinyu 回复

我现在换成下面的实现了. 可以搜索单个字段,或者所有的字符串字段。

module Searchable
extend ActiveSupport::Concern

  module ClassMethods
    def search(search, attributes: nil)
      if attributes.nil?
        attributes = []
        self.columns_hash.each { |k,v| attributes << k if [:string, :text].include? v.type  }
      end
      # attributes = self.new.attributes.keys - ["id", "created_at", "updated_at"] if attributes.nil?
      like_sql = attributes.map { |attr| %Q("#{attr}" LIKE ?) }.join("OR ")

      where(like_sql, *(["%#{search}%"]*attributes.size))
    end
  end

end

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