Class: Yodatra::ModelsController

Inherits:
Sinatra::Base
  • Object
show all
Defined in:
lib/yodatra/models_controller.rb

Overview

This is a generic model controller that expose a REST API for your models. The responses are encoded in JSON.

Simply create your controller that inherits from this class, keeping the naming convention.

For example, given a ‘User` model, creating a `class UsersController < Yodatra::ModelsController`, it will expose these routes:

GET /users

> retrieves all users _(attributes exposed are limited by the read_scope method defined in the UsersController)_

GET /users/:id

> retrieves a user _(attributes exposed are limited by the ‘read_scope“ method defined in the `UsersController`)_

POST /users

> creates a user _(attributes assignable are limited by the ‘user_params` method defined in the `UsersController`)_

PUT /users/:id

> updates a user _(attributes assignable are limited by the ‘user_params` method defined in the `UsersController`)_

DELETE /users/:id

> deletes a user

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 ‘Team` model that has many `User`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

DESTROY /team/:team_id/users/:id

Note:

You can disable any of these actions by using the ::disable class method and providing the list of actions you want to disable

disable :read, :read_all, :create, :update, :delete, :nested_read_all, :nested_delete

Extra:

You can enable a special “search” action by using the ::enable_search_on class method

enable_search_on :name

Constant Summary collapse

ONE_ROUTE =

Generic route to target ONE resource

%r{\A/([\w]+?)/([0-9]+)(?:/([\w]+?)/([0-9]+)){0,1}\Z}
ALL_ROUTE =

Generic route to target ALL resources

%r{\A/([\w]+?)(?:/([0-9]+)/([\w]+?)){0,1}\Z}
SEARCH_ROUTE =

Search route

%r{\A/([\w]+?)(?:/([0-9]+)/([\w]+?)){0,1}/search\Z}
READ_ALL =
:read_all
READ_ONE =
:read
CREATE_ONE =
:create
UPDATE_ONE =
:update
DELETE_ONE =
:delete

Class Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args) ⇒ Object (private)

create/update scope defaults to all data given in the POST/PUT



251
252
253
254
255
# File 'lib/yodatra/models_controller.rb', line 251

def method_missing(name, *args)
  if name.to_s == "#{model_name.underscore}_params"
    return params.reject{|k,v| %w(splat captures id updated_at created_at).include? k}
  end
end

Class Method Details

.disable(*opts) ⇒ Object

This helper gives the ability to disable default root by specifying a list of routes to disable.

Parameters:

  • *opts

    list of routes to disable (e.g. :create, :destroy)



133
134
135
136
137
138
139
# File 'lib/yodatra/models_controller.rb', line 133

def disable(*opts)
  opts.each do |key|
    method = "#{key}_disabled?".to_sym
    undef_method method if method_defined? method
    define_method method, Proc.new {|| true}
  end
end

.enable_search_on(*attributes) ⇒ Object

This class method enables the search routes ‘/resoures/search?q=search+terms` for the model. The search will be performed on all the attributes given in parameter of this method. E.g. if you enabled the search on `:name` and `:email` attrs a GET /resources/search?q=john+doe will return all `Resource` instance where the name or the email matches either “john” or “doe”



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/yodatra/models_controller.rb', line 146

def enable_search_on(*attributes)
  self.instance_eval do
    get SEARCH_ROUTE do
      retrieve_resources '' do |resource|

        pass if !involved? || params[:q].blank? || params[:q].size > 100

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

        # Seperate terms to match
        terms.each do |term|
          attributes.each do |attr|
            search_terms << resource.arel_table[attr.to_sym].matches("%#{term}%")
          end
        end

        resource.where(search_terms.reduce(:or)).limit(100).
          flatten.as_json(read_scope)
      end
    end
  end
end

.modelObject



126
127
128
# File 'lib/yodatra/models_controller.rb', line 126

def model
  model_name.constantize
end

.model_nameObject



122
123
124
# File 'lib/yodatra/models_controller.rb', line 122

def model_name
  self.name.split('::').last.gsub(/sController/, '')
end