API apps scaffold generator generates an apropriate controller

This commit is contained in:
Santiago Pastorino 2015-04-19 18:22:14 -04:00
parent 20939b3fcc
commit d4fe23c76b
6 changed files with 180 additions and 2 deletions

@ -10,11 +10,14 @@ class ScaffoldControllerGenerator < NamedBase # :nodoc:
class_option :helper, type: :boolean
class_option :orm, banner: "NAME", type: :string, required: true,
desc: "ORM to generate the controller for"
class_option :api, type: :boolean,
desc: "Preconfigure smaller stack for API only apps"
argument :attributes, type: :array, default: [], banner: "field:type field:type"
def create_controller_files
template "controller.rb", File.join('app/controllers', controller_class_path, "#{controller_file_name}_controller.rb")
template_file = options.api? ? "api_controller.rb" : "controller.rb"
template template_file, File.join('app/controllers', controller_class_path, "#{controller_file_name}_controller.rb")
end
hook_for :template_engine, :test_framework, as: :scaffold

@ -0,0 +1,63 @@
<% if namespaced? -%>
require_dependency "<%= namespaced_file_path %>/application_controller"
<% end -%>
<% module_namespacing do -%>
class <%= controller_class_name %>Controller < ApplicationController
before_action :set_<%= singular_table_name %>, only: [:show, :update, :destroy]
# GET <%= route_url %>
def index
@<%= plural_table_name %> = <%= orm_class.all(class_name) %>
render json: <%= "@#{plural_table_name}" %>
end
# GET <%= route_url %>/1
def show
render json: <%= "@#{singular_table_name}" %>
end
# POST <%= route_url %>
def create
@<%= singular_table_name %> = <%= orm_class.build(class_name, "#{singular_table_name}_params") %>
if @<%= orm_instance.save %>
render json: <%= "@#{singular_table_name}" %>, status: :created, location: <%= "@#{singular_table_name}" %>
else
render json: <%= "@#{orm_instance.errors}" %>, status: :unprocessable_entity
end
end
# PATCH/PUT <%= route_url %>/1
def update
if @<%= orm_instance.update("#{singular_table_name}_params") %>
head :no_content
else
render json: <%= "@#{orm_instance.errors}" %>, status: :unprocessable_entity
end
end
# DELETE <%= route_url %>/1
def destroy
@<%= orm_instance.destroy %>
head :no_content
end
private
# Use callbacks to share common setup or constraints between actions.
def set_<%= singular_table_name %>
@<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
end
# Only allow a trusted parameter "white list" through.
def <%= "#{singular_table_name}_params" %>
<%- if attributes_names.empty? -%>
params[:<%= singular_table_name %>]
<%- else -%>
params.require(:<%= singular_table_name %>).permit(<%= attributes_names.map { |name| ":#{name}" }.join(', ') %>)
<%- end -%>
end
end
<% end -%>

@ -8,10 +8,14 @@ class ScaffoldGenerator < Base # :nodoc:
check_class_collision suffix: "ControllerTest"
class_option :api, type: :boolean,
desc: "Preconfigure smaller stack for API only apps"
argument :attributes, type: :array, default: [], banner: "field:type field:type"
def create_test_files
template "functional_test.rb",
template_file = options.api? ? "api_functional_test.rb" : "functional_test.rb"
template template_file,
File.join("test/controllers", controller_class_path, "#{controller_file_name}_controller_test.rb")
end

@ -0,0 +1,41 @@
require 'test_helper'
<% module_namespacing do -%>
class <%= controller_class_name %>ControllerTest < ActionController::TestCase
setup do
@<%= singular_table_name %> = <%= table_name %>(:one)
end
test "should get index" do
get :index
assert_response :success
assert_not_nil assigns(:<%= table_name %>)
end
test "should create <%= singular_table_name %>" do
assert_difference('<%= class_name %>.count') do
post :create, params: { <%= "#{singular_table_name}: { #{attributes_hash} }" %> }
end
assert_response 201
end
test "should show <%= singular_table_name %>" do
get :show, params: { id: <%= "@#{singular_table_name}" %> }
assert_response :success
end
test "should update <%= singular_table_name %>" do
patch :update, params: { id: <%= "@#{singular_table_name}" %>, <%= "#{singular_table_name}: { #{attributes_hash} }" %> }
assert_response 204
end
test "should destroy <%= singular_table_name %>" do
assert_difference('<%= class_name %>.count', -1) do
delete :destroy, params: { id: <%= "@#{singular_table_name}" %> }
end
assert_response 204
end
end
<% end -%>

@ -194,6 +194,26 @@ def test_scaffold_tests_pass_by_default
assert_no_match(/Errors running/, output)
end
def test_api_scaffold_tests_pass_by_default
add_to_config <<-RUBY
config.api_only = true
config.generators.api_only = true
RUBY
app_file "app/controllers/application_controller.rb", <<-RUBY
class ApplicationController < ActionController::API
end
RUBY
output = Dir.chdir(app_path) do
`rails generate scaffold user username:string password:string;
bundle exec rake db:migrate test`
end
assert_match(/5 runs, 8 assertions, 0 failures, 0 errors/, output)
assert_no_match(/Errors running/, output)
end
def test_scaffold_with_references_columns_tests_pass_when_belongs_to_is_optional
app_file "config/initializers/active_record_belongs_to_required_by_default.rb",
"Rails.application.config.active_record.belongs_to_required_by_default = false"

@ -185,4 +185,51 @@ def test_controller_tests_pass_by_default_inside_mountable_engine
assert_match(/2 runs, 2 assertions, 0 failures, 0 errors/, `bundle exec rake test 2>&1`)
end
end
def test_api_only_generates_a_proper_api_controller
run_generator ["User", "--api"]
assert_file "app/controllers/users_controller.rb" do |content|
assert_match(/class UsersController < ApplicationController/, content)
assert_no_match(/respond_to/, content)
assert_match(/before_action :set_user, only: \[:show, :update, :destroy\]/, content)
assert_instance_method :index, content do |m|
assert_match(/@users = User\.all/, m)
assert_match(/render json: @users/, m)
end
assert_instance_method :show, content do |m|
assert_match(/render json: @user/, m)
end
assert_instance_method :create, content do |m|
assert_match(/@user = User\.new\(user_params\)/, m)
assert_match(/@user\.save/, m)
assert_match(/@user\.errors/, m)
end
assert_instance_method :update, content do |m|
assert_match(/@user\.update\(user_params\)/, m)
assert_match(/@user\.errors/, m)
end
assert_instance_method :destroy, content do |m|
assert_match(/@user\.destroy/, m)
end
end
end
def test_api_controller_tests
run_generator ["User", "name:string", "age:integer", "organization:references{polymorphic}", "--api"]
assert_file "test/controllers/users_controller_test.rb" do |content|
assert_match(/class UsersControllerTest < ActionController::TestCase/, content)
assert_match(/test "should get index"/, content)
assert_match(/post :create, params: \{ user: \{ age: @user\.age, name: @user\.name, organization_id: @user\.organization_id, organization_type: @user\.organization_type \} \}/, content)
assert_match(/patch :update, params: \{ id: @user, user: \{ age: @user\.age, name: @user\.name, organization_id: @user\.organization_id, organization_type: @user\.organization_type \} \}/, content)
assert_no_match(/assert_redirected_to/, content)
end
end
end