Skip to content

Commit

Permalink
Merge 8634fc8 into 99acf34
Browse files Browse the repository at this point in the history
  • Loading branch information
EvgeneOskin committed Nov 10, 2015
2 parents 99acf34 + 8634fc8 commit 2b6c2bf
Show file tree
Hide file tree
Showing 10 changed files with 176 additions and 17 deletions.
4 changes: 4 additions & 0 deletions Gemfile
Expand Up @@ -44,6 +44,10 @@ gem 'bcrypt', '~> 3.1.7'
gem 'bootstrap-sass', '>= 3.3.5'
gem 'sprockets-rails', '>= 2.3.3'

# REST API framework.
gem 'grape'
gem 'grape-entity'

group :production do
# Use Unicorn as the app server
gem 'unicorn'
Expand Down
34 changes: 34 additions & 0 deletions Gemfile.lock
Expand Up @@ -55,6 +55,10 @@ GEM
autoprefixer-rails (6.1.0.1)
execjs
json
axiom-types (0.1.1)
descendants_tracker (~> 0.0.4)
ice_nine (~> 0.11.0)
thread_safe (~> 0.3, >= 0.3.1)
bcrypt (3.1.10)
binding_of_caller (0.7.2)
debug_inspector (>= 0.0.1)
Expand All @@ -66,6 +70,8 @@ GEM
thor (~> 0.19)
builder (3.2.2)
byebug (8.0.1)
coercible (1.0.0)
descendants_tracker (~> 0.0.1)
coffee-rails (4.1.0)
coffee-script (>= 2.2.0)
railties (>= 4.0.0, < 5.0)
Expand All @@ -82,6 +88,8 @@ GEM
datetime_picker_rails (0.0.5)
momentjs-rails (>= 2.8.1)
debug_inspector (0.0.2)
descendants_tracker (0.0.4)
thread_safe (~> 0.3, >= 0.3.1)
devise (3.5.2)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
Expand All @@ -92,6 +100,7 @@ GEM
docile (1.1.5)
domain_name (0.5.25)
unf (>= 0.0.5, < 1.0.0)
equalizer (0.0.11)
erubis (2.7.0)
execjs (2.6.0)
factory_girl (4.5.0)
Expand All @@ -105,10 +114,24 @@ GEM
multipart-post (>= 1.2, < 3)
globalid (0.3.6)
activesupport (>= 4.1.0)
grape (0.13.0)
activesupport
builder
hashie (>= 2.1.0)
multi_json (>= 1.3.2)
multi_xml (>= 0.5.2)
rack (>= 1.3.0)
rack-accept
rack-mount
virtus (>= 1.0.0)
grape-entity (0.4.8)
activesupport
multi_json (>= 1.3.2)
hashie (3.4.3)
http-cookie (1.0.2)
domain_name (~> 0.5)
i18n (0.7.0)
ice_nine (0.11.1)
inline_svg (0.6.1)
activesupport (>= 4.0.4)
loofah (>= 2.0)
Expand Down Expand Up @@ -199,6 +222,10 @@ GEM
pg (0.18.3)
powerpack (0.1.1)
rack (1.6.4)
rack-accept (0.4.5)
rack (>= 0.4)
rack-mount (0.8.3)
rack (>= 1.0.0)
rack-test (0.6.3)
rack (>= 1.0)
rails (4.2.3)
Expand Down Expand Up @@ -291,6 +318,11 @@ GEM
kgio (~> 2.6)
rack
raindrops (~> 0.7)
virtus (1.0.5)
axiom-types (~> 0.1)
coercible (~> 1.0)
descendants_tracker (~> 0.0, >= 0.0.3)
equalizer (~> 0.0, >= 0.0.9)
warden (1.2.3)
rack (>= 1.0)
web-console (2.2.1)
Expand All @@ -313,6 +345,8 @@ DEPENDENCIES
devise
factory_girl_rails
faker
grape
grape-entity
jbuilder (~> 2.0)
jquery-rails
omniauth
Expand Down
59 changes: 59 additions & 0 deletions app/api/animal/api.rb
@@ -0,0 +1,59 @@
module Animal
# Class with grape api for Animal project.
class API < Grape::API
version 'v1', using: :path
format :json

helpers do
def current_user
@current_user ||= User.authorize!(env)
end

def authenticate!
error!('401 Unauthorized', 401) unless current_user
end
end

http_basic do |username, password|
# verify user's password here
user = User.find_by email: username
user.valid_password? password if user
end

desc 'Pet index.', params: Entities::Pet.documentation
get '/pet' do
authenticate!
pets = Pet.all
present pets, with: Entities::Pet, type: :full
end

desc 'Create a pet.', params: Entities::Pet.documentation
params do
requires(
:all,
except: [:id, :email],
using: Entities::Pet.documentation.except(:id, :email)
)
end
post '/pet' do
authenticate!
Pet.transaction do
Pet.create_with_params! params, @current_user
end
end

desc 'Breed index.', params: Entities::Breed.documentation
get '/breed' do
authenticate!
breeds = Breed.all
present breeds, with: Entities::Breed, type: :full
end

desc 'Birth index.', params: Entities::Birth.documentation
get '/birth' do
authenticate!
births = Birth.all
present births, with: Entities::Birth, type: :full
end
end
end
36 changes: 36 additions & 0 deletions app/api/animal/entities.rb
@@ -0,0 +1,36 @@
module Animal
# Entities for Animal API.
module Entities
# General Entity with id, and timestamps.
class Id < Grape::Entity
expose :id
expose :created_at
expose :updated_at
end

# General Entity plus name field.
class Named < Id
expose :name
end

# Pet entity (Pet and Birth model).
class Pet < Named
expose :email, as: :owner_email
expose :breed_id
expose :gender
expose :father_id
expose :mother_id
end

# Breed entity like Breed model.
class Breed < Named
end

# Birth entity like Birth model.
class Birth < Id
expose :child_id
expose :father_id
expose :mother_id
end
end
end
16 changes: 1 addition & 15 deletions app/controllers/pets_controller.rb
Expand Up @@ -8,26 +8,12 @@ def new
def create
Pet.transaction do
pet = create_pet
create_birth(pet)
redirect_to action: 'show', id: pet.id
end
end

def create_pet
Pet.create! do |p|
p.name = params[:name]
p.breed_id = params[:breed_id]
p.gender = params[:gender]
p.owner = current_user
end
end

def create_birth(pet)
Birth.create! do |b|
b.child = pet
b.mother_id = params[:mother_id]
b.father_id = params[:father_id]
end
Pet.create_with_params! params, current_user
end

def index
Expand Down
29 changes: 29 additions & 0 deletions app/models/pet.rb
Expand Up @@ -10,6 +10,8 @@ class Pet < ActiveRecord::Base
validates :owner, presence: true
validates :gender, presence: true

delegate :email, to: :owner

def birth
Birth.find_by child: self
end
Expand All @@ -22,6 +24,14 @@ def mother
birth.mother if birth && birth.mother
end

def father_id
father.id if father
end

def mother_id
mother.id if mother
end

def children
if gender == 'male'
births = Birth.where father: self
Expand All @@ -31,6 +41,25 @@ def children
births.includes(:child).map(&:child)
end

def self.create_with_params!(params, user)
pet = self.create! do |p|
p.name = params[:name]
p.breed_id = params[:breed_id]
p.gender = params[:gender]
p.owner = user
end
pet.create_birth_with_params! params
pet
end

def create_birth_with_params!(params)
Birth.create! do |b|
b.child = self
b.mother_id = params[:mother_id]
b.father_id = params[:father_id]
end
end

def self.where_can_be_father
where gender: 0
end
Expand Down
4 changes: 4 additions & 0 deletions app/models/user.rb
Expand Up @@ -4,4 +4,8 @@ class User < ActiveRecord::Base
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable

def self.authorize!(env)
find_by email: env['REMOTE_USER']
end
end
6 changes: 5 additions & 1 deletion config/application.rb
Expand Up @@ -6,7 +6,7 @@
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module HelloAnimalsRails
module AnimalsRails
# Rails Application
class Application < Rails::Application
# Settings in config/environments/* take precedence over those
Expand All @@ -29,5 +29,9 @@ class Application < Rails::Application

# Do not swallow errors in after_commit/after_rollback callbacks.
config.active_record.raise_in_transactional_callbacks = true

# Add REST API to app.
config.paths.add 'app/api', glob: '**/*.rb'
config.autoload_paths += Dir["#{Rails.root}/app/api/*"]
end
end
2 changes: 1 addition & 1 deletion config/initializers/session_store.rb
@@ -1,5 +1,5 @@
# Be sure to restart your server when you modify this file.

Rails.application.config.session_store(
:cookie_store, key: '_hello_animals_rails_session'
:cookie_store, key: '_animals_rails_session'
)
3 changes: 3 additions & 0 deletions config/routes.rb
Expand Up @@ -11,6 +11,9 @@
resources :pets

devise_for :users

mount Animal::API => '/api'

# The priority is based upon order of creation: first created -> highest
# priority.
# See how all your routes lay out with "rake routes".
Expand Down

0 comments on commit 2b6c2bf

Please sign in to comment.