Last active
August 29, 2015 14:07
-
-
Save jeffrwells/6d45cb050a0f650eca85 to your computer and use it in GitHub Desktop.
Incoming API setup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Api::V1::BaseController < ApplicationController | |
respond_to :json | |
before_action :authenticate! #make this the default, then you could use skip_before_action on an action you don't need it | |
def authenticate! | |
load_account || access_denied | |
end | |
def access_denied | |
head :unauthorized and return | |
end | |
def not_found | |
raise ActionController::RoutingError.new('Not Found') # this will trigger 404 - acts as if no route matched | |
end | |
def api_account | |
@api_account ||= find_api_account! | |
end | |
def find_api_account! | |
User.find_by!(api_key: (params[:api_key] || request.headers['api_key']) ) | |
# find_by! will trigger 404 also if not found | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Api::V1::UsersController < Api::V1::BaseController | |
# GET /api/v1/user/3 | |
def show | |
@user = api_account.users.find(params[:id]) | |
render json: @user.as_json(root: true, only: [:has_iphone, :and, :other, :allowable, :attributes] | |
end | |
def create | |
@user = Api::User.create!(api_account, params.require(:user)) #delegate this to lib, don't do it in controller | |
render json @user.as_json #etc... | |
# you can start to see why active_model_serializer will keep your code dry. | |
# All you need to do is define the serializer and then call render json: @user, root: true (I think) | |
end | |
#... | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Api::User | |
#note that it isn't a class | |
def create!(account, user_params) | |
user = account.find_or_initialize_by(email: user_params['email']) #email or whatever your pniqueness is | |
# or just User.new, up to you | |
#note scoped to account ^. this will autofill account_id on the new user | |
user.approved_attr = user_params['approved_attr'] | |
#etc etc | |
user.data = user_params | |
user.save! #would use bang here to bubble up to response throwing a 500 if it fails | |
return user | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rails_helper' | |
describe Api::User do | |
let (:subject) { Api::User } | |
describe '.create!' do | |
let(:account} { Fabricate :account } | |
let(:params) { {name: 'bob', availability: {monday: true}} } | |
it 'returns a user' do | |
expect(subject.create!(account, params)).to be_a(User) | |
end | |
it 'saves approved attributes to the user' do | |
user = subject.create!(account, params) | |
expect(user.name).to eq('bob') | |
end | |
it 'stores arbitrary attributes to the data column' do | |
user = subject.create!(account, params) | |
expect(user.data).to eq(params) | |
end | |
it 'throws an error if the user doesn't save' do | |
user_with_missing_necessary_attribute = User.new | |
allow(account).to receieve(:find_or_initialize_by).and_return(user_with_missing_necessary_attribute) | |
expect { | |
user = subject.create!(account, params) | |
}.to raise_error | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@jeffrwells is it fine that the controller file name is "class Api::V1::BaseController < ApplicationController"
instead of
module Api
module V1
class BaseController < ApplicationController
end
end
end