Rails Rails 定制简单的搜索

zengfengbo · June 23, 2017 · Last by zengfengbo replied at November 24, 2017 · 1738 hits

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 Floor has deleted
Reply to ad583255925

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

Reply to zengfengbo

推荐 ransack

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

Reply to 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

You need to Sign in before reply, if you don't have an account, please Sign up first.