I have the following ajax function
$.ajax({
url: '/sub_categories/sub_cat',
data: 'sub_cat=45',
success: function() {
alert('success');
}
})
Here is my controller
require 'json'
class SubCategoriesController < ApplicationController
def show
end
def sub_cat
#sub_categories = SubCategory.where(category_id: params[:cat_id])
html = render_to_string 'sub_categories/sub_cat'
response_html true,html
end
end
My application controller
def response_html status,html
respond_to do |format|
format.json {render json: {
status: status,
html: html,
}
}
format.html
end
end
I have json file in sub_categories/sub_cat.json.erb
When I run getting error as
ActionView::MissingTemplate at /sub_categories/sub_cat.json
Missing template sub_categories/show, application/show with {:locale=>[:en], :formats=>[:json], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder, :coffee]}. Searched in:
* "/home/editmehere/Documents/site/name/app/views"
My route.rb has
resources :sub_categories do
get 'sub_cat', on: :collection
end
Why I am getting error like this and how can I solve it. Can anyone help me to solve it.
I'm guessing you're trying to keep your application dry, but why don't you just use this in your SubCategoriesController:
class SubCategoriesController < ApplicationController
def sub_cat
#sub_categories = SubCategory.where(category_id: params[:cat_id])
respond_to do |format|
format.json
format.html
end
end
end
This will allow you to call sub_cat.json.erb without having to pass the status var, or pre-render the HTML. This is just convention, so apologies if it's not what you need. I see a lot of people on here overcomplicate things, when simplicity would work much better
Ajax
Also, I believe you've got a problem with your ajax data var:
data: 'sub_cat=45',
should be
data: {sub_cat: "45"},
Related
Has anyone come across this error before? I've looked online and couldn't find much information, perhaps I didn't render my JSON correctly?
Missing template answer/results, application/results with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :coffee, :jbuilder]}. Searched in: * "/Users/Minhaj/Desktop/my_survey/my_survey/app/views" * "/Users/Minhaj/.rvm/gems/ruby-2.4.1/gems/devise-4.5.0/app/views"
Here is the code. If there is an error, help will be appreciated in fixing it.
def create
#answer = current_survey.answers.create(question_id: question, choice_id: choice)
redirect_to question_survey_path(current_survey)
end
def results
#choices = choices_hash
#results = questions.map do |question|
{
question.question => CountChoicesService.call(question.id)
}
end
respond_to do |format|
format.html { render :nothing => true, :status => 204 }
format.json { render json: #results }
end
end
private
def question
#question ||= params[:question]
end
def choice
#choice ||= params[:choice]
end
def choices
#choices ||= Array.wrap(Choice.all)
end
def choices_hash
choices_hash = {}
choices.each { |choice| choices_hash[choice.id] = choice.choice }
choices_hash
end
def questions
#questions ||= Array.wrap(Question.all)
end
end
I appreciate the help in advance.
Here is how it should look like, controller name is plural
Under your controller directory, you should have this
# app/controller/answers_controller.rb
class AnswersController < ApplicationController
def results
end
end
Now in the views directory,the view namespace should be the same as the controller name.
# app/views/answers/results.html.erb
<h1>Check if this works</h1>
routes.rb
resources :answers do
collection/member do
get :results
end
end
Your problem is that you are not returning. Rails will render the associated template for the action unless you return. Try wrapping your render calls in return().
Side note, why are you using Array.wrap()? ActiveRecord’s all methods are array-like. They wait to execute the query until you actually try to iterate them, and then they act like an array. You shouldn’t need to make them an array. If you ever find that you do, you can call .to_a on them.
One thing to note about the active record record collection though, if you remove anything from its “array”, it will actually do a delete from the database, which may or may not be what you want.
I am creating a new version of one of my controllers,
Original Controller:-
class ExampleController < ApplicationController
layout 'filename', only: [:method_name]
...
def method_name
#...some logic...
respond_to do |format|
format.html
format.json {
render json: {}, root: false
}
end
end
...
end
New Controller:-
class V1::ExampleController < ApplicationController
layout 'filename', only: [:method_name]
...
def method_name
#...some logic...
respond_to do |format|
format.html
format.json {
render json: {}, root: false
}
end
end
...
end
I keep getting error:-
Missing template v1/example/filename, application/filename with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :arb, :haml, :jbuilder]}
One of the solution is to create a folder structure v1/example and put my layout file there too. But I do not want to create duplicate copies of this file.
Another is to use a parent controller class of both new and old example_controller and specify layout there(and have a folder structure according to the name of the parent class). But this will be an overkill and also I plan on deleting old controller once all my clients migrate to new versions.
I also tried specifying like this:-
class V1::ExampleController < ApplicationController
layout 'example/filename', only: [:method_name]
...
end
but this also doesn't work.
How to tell my new controller to render layout from the old folder structure.
format.html {
render template: 'path/to/template'
}
Rendering a template
Template rendering works just like action rendering except that it
takes a path relative to the template root. The current layout is
automatically applied.
# Renders the template located in [TEMPLATE_ROOT]/weblog/show.r(html|xml) (in Rails, app/views/weblog/show.erb)
render :template => "weblog/show"`
See reference for #render
In my routes.rb I have:
resources :workouts
In my workouts controller I have:
def show
respond_to do |format|
format.html
format.json { render :json => "Success" }
end
end
But when I go to /workouts/1.json, I receive the following:
Template is missing
Missing template workouts/show, application/show with {:locale=>[:en], :formats=>[:json], :handlers=>[:erb, :builder, :coffee]}. Searched in: * "/home/rails/app/views"
Which appears to show that the format is what it should be but it's still searching for a view. This same code functions in other controllers with identical setups just fine. Also, going to /workouts/1 for the html view seems to work just fine, though it also renders the html view properly when the format.html is removed.
Looks at the source code of render
elsif options.include?(:json)
json = options[:json]
json = ActiveSupport::JSON.encode(json) unless json.is_a?(String)
json = "#{options[:callback]}(#{json})" unless options[:callback].blank?
response.content_type ||= Mime::JSON
render_for_text(json, options[:status])
Pay attention to the third line. If the value of :json is a string, render won't call to_json automatically for this value.
So the value remains as string and render will go on to search template.
To fix, supply a valid hash even for trying purpose.
format.json { render :json => {:message => "Success"} }
You would try with /workouts.json
I am trying to execute an AJAX routine with rails
the code runs normally but the response doesnt..
I get this error
Template is missing
Missing template line_items/create, application/create with {:locale=>[:en], :formats=>[:js, :html], :handlers=>[:erb, :builder, :coffee]}. Searched in: * "D:/ruby/depot/app/views"
I created the create.js.rjs inside line_items directory like the book Agile Web Development says it is to be, but the error insists..
#file line_items_controller.rb
def create
#cart = current_cart
product = Product.find(params[:product_id])
#line_item = add_product(#cart, product.id)
respond_to do |format|
if #line_item.save
format.html { redirect_to store_url }
format.js
format.json { render json: #line_item, status: :created, location: #line_item }
#...
end
end
end
and inside my create.js.rjs I got this
page.replace_html('cart', render(#cart))
Rjs is not a valid format anymore I guess. Use js.erb instead. Also manual you're following is outdated since none uses prototype anymore.
I'm trying to render a liquid template that is stored in the database.
Here is my 'show' action in the controller:
def show
#organization = Organization.find_by_subdomain(request.subdomain)
#template = Liquid::Template.parse(Template.find(#organization.current_template).body)
#page = #organization.pages.find(params[:id])
respond_to do |format|
format.html { render #template.render('page' => #page), :template => false}
format.json { render json: #page }
end
end
However, when I visit the page, I get a "Template is Missing" exception with the following error (note that "testing testing" is the body attribute of the page object, which is currently the only thing being rendered in the template):
Missing template /testing testing with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :coffee, :haml]}.
Searched in: * "/Users/ashercohen/Documents/Rails/Vocalem-Rails/app/views"
* "/Users/ashercohen/.rvm/gems/ruby-1.9.3-p194/gems/twitter-bootstrap-rails-2.1.1/app/views"
* "/Users/ashercohen/.rvm/gems/ruby-1.9.3-p194/gems/devise-2.1.2/app/views"
Why is it trying to find another template, when I've specifically pass the :template => false argument? Is there something I'm missing here? I'm trying to bypass using any template files, as it seems like they shouldn't be needed here (though am not strongly opposed if I am wrong).
Because render almost always takes a filename, while #template.render('page' => #page) contains the plain html. You should invoke render like this:
render :text => #template.render('page' => #page), :content_type => :html