8
votes

So I'm testing out a very simple API in Rails to see if I can create a user from it locally using the Chrome plugin Postman (REST Client extension).

In my rails app, I've set up a folder/namespace for my API, and whenever I try to create my user, I get the following error: Missing template api/v1/users/create, application/create with {:locale=>[:en], :formats=>[:json], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder, :coffee]}. Searched in: * "PATH/app/views"

I'm using Rails 4.0.1 and Ruby 2.0

I'm posting a screenshot below of what I'm posting:

Screenshot 1

module Api
     module V1
    class UsersController < ApplicationController
        class User < ::User
            # add any hacks
        end

        respond_to :json

        def index
            respond_with User.all
        end

        def show
            respond_with User.find(params[:id])
        end

        def new
            @user = User.new
        end

        def create
            @user = User.create(user_params)
            # respond_with(@user)

            if @user.save
                # render json: @user, status: :created, location: @user
                redirect_to @user
            end
        end

        private

            def user_params
              params.require(:user).permit(:name, :age, :location) if params[:user]
            end
    end
  end
end

So based on my user_params, I should be able to create a new user, correct? Please let me know if you need any additional info and I'll do my best to respond ASAP! Thanks!

2

2 Answers

22
votes

You can create user using API.

1) First you need to put proper resources in your routes.rb:

YourApp::Application.routes.draw do
  namespace :api do
    namespace :v1 do
     resources :users
    end
    namespace :v2 do
    # ... if needed
    end
  end

  root to: 'users#index'
end

2) You need to create a RESTfull-style controller to process requests. Here how your action 'create' may be implemented.

def create
  respond_with User.create(fio: params[:fio], phone: params[:phone], region: params[:region], updated_at: Time.now)
end

Example of 'create' with respond_to:

def create
    # ...
    respond_to do |format|
      format.html {render text: "Your data was sucessfully loaded. Thanks"}
      format.json { 
                   User.create(... params ...)
                   render text: User.last.to_json  # !
                  }
    end
  end

See documents about respond_with and respond_to if you need something special to respond.

Also can be helpful railscasts episodes about API building: #350 and #352

P.S. folder/namespace/v1/users_controller shall be the same as class name in your module Api

P.S.2 You can observe my app, where you can probably find something helpful (same as your app - simple API for records creating) - myApp

Example of users_controller (controllers/api/v1/users_controller.rb):

#encoding: utf-8

    module Api
      module V1
        class UsersController < ApplicationController # Api::BaseController
          before_filter :authenticate_user!, except: [:create, :index]

          respond_to :json

          def index
        #respond_with

            respond_to do |format|
              format.html {render text: "Your data was sucessfully loaded. Thanks"}
              format.json { render text: User.last.to_json }
            end
          end

          def show
            respond_with User.find(params[:id])
          end

          def create
            respond_with User.create(access_token: params[:access_token], city: params[:city], created_at: Time.now, phone: params[:phone], region: params[:region], updated_at: Time.now)
          end

          def update
            respond_with User.update(params[:id], params[:users])
          end

          def destroy
            respond_with User.destroy(params[:id])
          end
        end
      end
    end
0
votes

redirect dose not return, so your create method will keep looking for template to render, and then find there is no matching template.

To fix, you need to explicitly return redirect

 if @user.save
   return redirect_to(@user)
 end

You also need to pay attention to the default url of @user. It's better to assign a named path explicitly in this case, say redirect_to(user_path(@user))