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



245
246
247
248
249
# File 'lib/yodatra/models_controller.rb', line 245

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)



129
130
131
132
133
134
135
# File 'lib/yodatra/models_controller.rb', line 129

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”



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/yodatra/models_controller.rb', line 142

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



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

def model
  model_name.constantize
end

.model_nameObject



118
119
120
# File 'lib/yodatra/models_controller.rb', line 118

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