Skip to content

Commit

Permalink
feat(search): wip on a search action for models
Browse files Browse the repository at this point in the history
  • Loading branch information
paulRbr committed Aug 8, 2014
1 parent 44eec1f commit 28be2fa
Showing 1 changed file with 63 additions and 0 deletions.
63 changes: 63 additions & 0 deletions lib/yodatra/models_controller.rb
Expand Up @@ -23,6 +23,12 @@ module Yodatra
# If your model is referenced by another model, nested routes are also created for you. And you don't need to worry about the references/joins, they are done automaticly!
# For example, imagine a <b>Team</b> model that has many <b>User</b>s, the following routes will be exposed:
# GET /team/:team_id/users, GET /team/:team_id/users/:id, POST /team/:team_id/users, PUT /team/:team_id/users/:id and DESTROY /team/:team_id/users/:id
#
# _Note_: You can disable any of these five actions by using the `#disable` class method
# and giving in parameters the list of actions you want to disable
# e.g. `disable :read, :read_all, :create, :update, :delete`
#
# _Note2_: You can enable a special "search" action by using the `#enable_search_on` class method
class ModelsController < Sinatra::Base

before do
Expand All @@ -37,6 +43,10 @@ class ModelsController < Sinatra::Base
ALL_ROUTE =
%r{\A/([\w]+?)(?:/([0-9]+)/([\w]+?)){0,1}\Z}

# Search route
SEARCH_ROUTE =
%r{\A/([\w]+?)/search\Z}

READ_ALL = :read_all
get ALL_ROUTE do
retrieve_resources READ_ALL do |resource|
Expand Down Expand Up @@ -118,6 +128,10 @@ def model_name
self.name.split('::').last.gsub(/sController/, '')
end

def model
model_name.constantize
end

# This helper gives the ability to disable default root by specifying
# a list of routes to disable.
# @param *opts list of routes to disable (e.g. :create, :destroy)
Expand All @@ -128,6 +142,51 @@ def disable(*opts)
define_method method, Proc.new {|| true}
end
end

def enable_search_on(*attributes)
self.instance_eval do
get SEARCH_ROUTE do
pass if !involved? || params[:q].blank? || params[:q].size > 100

terms = params[:q].split(/\+/)
#nested = []
search_terms = []
results = []

# Seperate terms to match
# from
# Scopes (words that include a ':')
terms.each do |term|
unless term.include? ':'
attributes.each do |attr|
search_terms << model.arel_table[attr.to_sym].matches("%#{term}%")
end
next
end

#sep = term.split(/:/)
#begin
# nested << sep.first.singularize.classify.constantize.send(:search, sep.second, true)
#rescue NameError
# scope doesn't exist
#end
end

# if nested.empty?
results << model
# else
# nested.each do |parent|
# results += parent.send(:users)
# end
# end

results.map do |result|
result.where(search_terms.reduce(:or)).limit(100)
end.flatten.as_json(UsersController.read_scope).to_json

end
end
end
end

private
Expand Down Expand Up @@ -181,6 +240,10 @@ def model_name
self.class.model_name
end

def model
self.class.model
end

def disabled? key
method = ((nested? ? 'nested_' : '')+"#{key}_disabled?").to_sym
self.class.method_defined?(method) && self.send(method)
Expand Down

0 comments on commit 28be2fa

Please sign in to comment.