Rails respond with JBuilder (AngularJS) - ruby-on-rails

i have a simple application to snooker league and i have a action add_player in LeaguesController. My client (AngularJS) call this action and i want to respond with json format using JBuilder. This working fine:
def add_player
...
render :json => #league.players.to_json(:only => [ :id, :firstname, :lastname, :max_break, :email ])
end
But when i delete this line and add:
respond_to do |format|
format.html
format.json
end
i have this error:
ActionView::MissingTemplate (
Missing template leagues/add_player,
application/add_player
with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder, :haml]}.
Searched in:
* "/home/daniel/SitesWWW/snookerLeague/app/views"
):
app/controllers/leagues_controller.rb:67:in `add_player'
Of course i have file add_player.json.jbuilder:
json.players #league.players do |player|
json.id player.id
json.firstname player.firstname.capitalize if player.firstname
json.lastname player.lastname.capitalize if player.lastname
json.email player.email
json.max_break player.max_break
end
So, what i should do?

Notice in your error message :formats=>[:html] this indicates to me it is trying to render add_player.html.erb and not your jbuilder template.
To verify this, try changing the calling code and append .json to the url which will force the format to be json.
You can also specify a default of json on your routes and not include it in the url:
resources :leagues, defaults: { format: :json } do
member do
post :add_player
end
end
see also: http://guides.rubyonrails.org/routing.html#defining-defaults

Related

ActionView::MissingTemplate even though template exists

I'm building a simple login screen. I'd like to return an :internal_server_error to my client if there isn't a matching user or if the password is incorrect. However, I'm getting the following missing template error:
ActionView::MissingTemplate (Missing template login/index,
application/index with {:locale=>[:en], :formats=>[:json],
:variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby,
:coffee, :jbuilder]}. Searched in: *
"C:/Shelf/myGroceryList/app/views"
What has me confused is that I have an index.html.erb template in views/login. Thoughts?
Route:
post '/login', to: 'login#show'
Controller(login_controller.rb):
class LoginController < ApplicationController
protect_from_forgery with: :null_session
def index
end
def show
username = params.values.last["email"]
password = params.values.last["password"]
loginType = params.values.last["loginType"]
if loginType == "Login"
login(username, password)
else
createNewUser(username, password)
end
end
def login(username, password)
begin
user = User.find_by(username: username)
raise(StandardError) if user.password != password
rescue
render 'index', :status => :internal_server_error
end
end
def createNewUser(username, password)
User.new(username: username, password: password)
end
end
View(index.html.erb):
<body><%= javascript_pack_tag 'login' %></body>
ActionView::MissingTemplate (Missing template login/index,
application/index with {:locale=>[:en], :formats=>[:json],
:variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby,
:coffee, :jbuilder]}. Searched in: *
"C:/Shelf/myGroceryList/app/views"
The error says it can't find the file with the name index and with the format json. As are you having an API, probably the request/response would be in the format json not html. That said you need to create a index.json.erb inside app/views/login to resolve the error.

Rails ActionView::MissingTemplate for templates that should not exist

I randomly get this error when in production from certain IP Addresses on the root path. The rails app does not support the formats :formats=>[:gif, "image/x-xbitmap", :jpeg, "image/pjpeg", "application/x-shockwave-flash", "application/vnd.ms-excel", "application/vnd.ms-powerpoint", "application/msword"] so this error seems to be expected if a request is being made for them. I'm guessing that someone or some bot is trying to run an exploit against the site -- how can I redirect or route these kinds of requests back to the route path such that an error is not produced?
ActionView::MissingTemplate: Missing template front_page/index, application/index with {:locale=>[:en], :formats=>[:gif, "image/x-xbitmap", :jpeg, "image/pjpeg", "application/x-shockwave-flash", "application/vnd.ms-excel", "application/vnd.ms-powerpoint", "application/msword"], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :arb, :jbuilder]}. Searched in:
* "/app/app/views"
* "/app/vendor/bundle/ruby/2.0.0/gems/activeadmin-1.0.0.pre2/app/views"
* "/app/vendor/bundle/ruby/2.0.0/gems/kaminari-0.16.3/app/views"
* "/app/vendor/bundle/ruby/2.0.0/gems/devise-3.5.2/app/views"
File "/app/vendor/bundle/ruby/2.0.0/gems/actionview-4.2.4/lib/action_view/path_set.rb", line 46, in find
File "/app/vendor/bundle/ruby/2.0.0/gems/actionview-4.2.4/lib/action_view/lookup_context.rb", line 121, in find
File "/app/vendor/bundle/ruby/2.0.0/gems/actionview-4.2.4/lib/action_view/renderer/abstract_renderer.rb", line 18, in find_template
The full error is here
To achieve the result desired in your comment:
constraints :format => "html" do
resources ...
end
Or if you need more flexibility:
# application_controller.rb
ApplicationController < ActionController::Base
before_action :check_format!
...
def check_format!
unless request.format == :html
render :nothing status: :bad_request
end
end
...
end
But overall, I feel like this is all a ton of overkill...
Plus, it's very typical to see buckets of respond_to in controllers, because the normal behaviour is to try and serve up the any format. Otherwise, there would probably be tons of configurations and such.
Is there a way to do this for all controller actions unless explicitly stated
So when you say unless explicitly stated you're sort of swimming against the current.
I'm not sure that this will work for you, but perhaps something like:
def index
...
respond_to do |format|
format.html
format.all { render status: :bad_request }
end
end

where to store a jbuilder template?

I'm attempting to use a jbuilder template.
Given the controller,
class Api::ReviewsController < ApplicationController
before_filter :authenticate_user!
respond_to :json
def create
#review_request = ReviewRequest.new(review_request_params.merge(user_id: current_user.id))
if #review_request.save
render 'review_requests/review'
else
head :forbidden
end
end
end
and I have the jbuilder template stored at app/views/review_requests/review.json.jbuilder
json.review_request do
json.(#review_request, :title,)
end
I'm getting a template note found error.
ActionView::MissingTemplate (Missing template review_requests/review with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}. Searched in:
* "/Users/jd/Dropbox/application-code/antipattern/app/views"
* "/Users/jd/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/devise-3.4.1/app/views"
* "/Users/jd/Dropbox/application-code/antipattern"
* "/"
):
app/controllers/api/reviews_controller.rb:8:in `create'
Any thoughts on either where the correct place to store this template is or why rails isn't finding the template i'm using (if the storage location happens to be ok)?
jbuilder needs a json type web request, an html request to a rails server will cause the jbuilder template to not be rendered.

ActionView::MissingTemplate error when using modules

I'm using a versioned API design from this RailsCasts episode and it's working great, except my jbuilder templates aren't rendering.
Here's my controller code:
module Api
module V1
class LocationsController < ApplicationController
respond_to :json
def index
#locations = Location.all
end
end
end
end
And my jbuilder file is at app/views/api/v1/locations/index.json.jbuilder
I get the following error:
ActionView::MissingTemplate (Missing template api/v1/locations/index,
api/v1/api/index, application/index with {:locale=>[:en], :formats=>[:json],
:variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}.
Searched in: * "/XXX/XXX/XXX/XXX/app/views"
EDIT: And here's the code in my routes.rb file:
namespace :api, defaults: { format: :json } do
namespace :v1 do
resources :locations, only: [ :index ]
end
end
Any ideas how I could debug this? Why are the files in the api folder not being found by Rails? Thanks!
I have this issue all the time. It can sometimes be a typo or error raised in the actual code within the json templates. Try commenting out all the lines in the index.json.jbuilder file, reload, work? Try uncommenting a line at a time. I haven't found a solution for better debugging this issue with jbuilder... yet.
in routes you should remove the defaults: { format: :json }

Respond to JSON is responding via HTML

In my Rails app, I have in the Application controller
respond_to :json
A controller that inherits Application controller responds with json like so in the action...
# Some code
if mission_updated.eql? true
render :json => {}
else
render :json => {}
end
However, whenever I run a rspec test in reference to the above action
it "should return appropriate response" do
post :update_unlocked_missions
parsed_body = JSON.parse(response.body)
parsed_body.should == {}
end
I'm returned with the following rspec error
ActionView::MissingTemplate:
Missing template api/v1/missions/update_unlocked_missions, api/v1/base/update_unlocked_missions with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :coffee, :rabl, :haml]}. Searched in:
* "#<RSpec::Rails::ViewRendering::EmptyTemplatePathSetDecorator:0x007f9ea2903b00>"
My question is why is it going to the view when it should respond with json and how do I fix this?
Try testing with an action that's just render json: {}. If that works, the problem is probably something in mission_updated.

Resources