Skip to content

Instantly share code, notes, and snippets.

@matsuda
Created February 1, 2010 02:01
Show Gist options
  • Save matsuda/291394 to your computer and use it in GitHub Desktop.
Save matsuda/291394 to your computer and use it in GitHub Desktop.
#
# 検索用クラス
# ActiveFormプラグインに似ている
#
# これまでのActiveSearchをモジュール化し、ActiveFormを拡張するようにしました
# selectable_attrがインクルードされています
# ------------------------------------------------------
# 使い方
# SearchFormクラスを継承
# Ext::ActiveSearch::Baseモジュールをインクルード
# active_search_for クラスメソッドで対象とするモデルを設定
# conditionsインスタンスメソッドの実装
# newでインスタンス生成
# paginateかfindで結果取得
# ------------------------------------------------------
# 例)
# model:lib/models/content_link_search.rb
#
# class ContentLinkSearch < ActiveForm
# include Ext::ActiveSearch::Base
# active_search_for 'ContentLink'
#
# def conditions
# conds ||= []
# conds << ["#{table_name}.http_status_code IS NOT NULL"] if self.status.present? && self.status == '1'
# conds << ["#{table_name}.url REGEXP ?", self.url] if self.url.present?
# conds << ["#{table_name}.description LIKE ?", "%#{self.description}%"] if self.description.present?
# conds.present? ? flatten_conditions(conds) : nil
# end
# end
#
# ------------------------------------------------------
# controller:app/controllers/admin/content_links_controller.rb
#
# class Admin::ContentLinksController < Admin::BaseController
# def index
# @content_link_search = ContentLink::Search.new(params[:content_link_search])
# @content_links = @content_link_search.paginate(
# :include => {:site => :company},
# :order => 'content_links.id desc',
# :page => params[:page],
# :per_page => per_page
# )
# end
# end
#
# ------------------------------------------------------
# view:app/views/admin/content_links/index.html.erb
#
# <%- form_for :content_link_search, :url => admin_content_links_path, :html => {:method => :get} do |f| -%>
# <table>
# <tr>
# <th>リンク先URL</th>
# <td><%= f.text_field :url %></td>
# </tr>
# <tr>
# <th>備考</th>
# <td><%= f.text_field :description %></td>
# </tr>
# <tr>
# <td>
# <%= f.check_box :status, :value => '0' %>未処理リンクのみ
# </td>
# <td><%= f.submit '検索' %></td>
# </tr>
# </table>
# <%- end -%>
#
module Ext
module ActiveSearch
module Base
def self.included(base) # :nodoc:
base.extend ClassMethods
base.class_eval do
extend Ext::ActiveSearch::Base::SingletonMethods
include Ext::ActiveSearch::Base::InstanceMethods
include Ext::ActiveRecord::FlattenCondition
include ::SelectableAttr::Base
end
end
module ClassMethods
def active_search_for(target, *attributes)
klass = target.constantize
set_class_name target
set_table_name klass.table_name
end
end
module SingletonMethods
private
def set_class_name(value)
define_attr_method :class_name, value
end
def set_table_name(value)
define_attr_method :table_name, value
end
# ActiveRecord::Base
def define_attr_method(name, value=nil, &block)
klass = class << self; self; end
if block_given?
klass.send :define_method, name, &block
else
# use eval instead of a block to work around a memory leak in dev
# mode in fcgi
klass.class_eval "def #{name}; #{value.to_s.inspect}; end"
end
end
end
module InstanceMethods #:nodoc:
def initialize(attributes, *opt)
@options = opt
super(attributes)
end
def table_name; self.class.table_name; end
def class_name; self.class.class_name; end
def options; @options; end
def conditions; end
def results
warn('[DEPRECATION] Ext::ActiveSearch::Base.results is deprecated ' +
'and will be removed from future versions. ' +
'Use Ext::ActiveSearch::Base.paginate instead')
opts = {}
opts[:conditions] = self.conditions if self.conditions.present?
self.class.class_name.constantize.paginate( opts.reverse_merge(options.extract_options!) )
end
def paginate(options)
options.delete(:conditions) if options[:conditions].present?
options[:conditions] = self.conditions if self.conditions.present?
self.class.class_name.constantize.paginate( options )
end
def find(*args)
options = args.extract_options!
options.delete(:conditions) if options[:conditions].present?
options[:conditions] = self.conditions if self.conditions.present?
self.class.class_name.constantize.find( args.first, options )
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment