I'm developing a preview for facebook crawlers using browser gem .The problem is on rendering point . I don't know how to set the respond_to block in the controller . Currently , I've the following
def show_preview
#question = to_array(#question)
question_package = formatting_questoins(#question,params[:id].to_i)
#searched_question = question_package.first
respond_with do |format|
format.html { render 'show_preview' }
end
end
It renders nothing . I tried with
respond_with do |format|
format.html { render 'show_preview' }
format.json
end
But it also renders nothing . Any help will be appreciating
Rails knows which view to use for each controller action by convention. Your action show_preview of your controller MyController will use the view views/my_controller/show_preview.html.erb.
You do not need to use respond_with nor render for that.
So your controller action becomes :
def show_preview
#question = to_array(#question)
question_package = formatting_questoins(#question,params[:id].to_i)
#searched_question = question_package.first
end
And your view views/my_controller/show_preview.html.erb can now use #question and #searched_question in order to render something.
Documentation : http://guides.rubyonrails.org/layouts_and_rendering.html#rendering-by-default-convention-over-configuration-in-action
Related
I looking for the correct way to do the following.
I have a controller action 'show' that really only gets a database entry like:
def show
#photo = Photo.find params[:photo_id]
end
I have four different views that all use the same controller action. How would I implement this?
I have thought of two ways:
1) use a url parameter:
def show
#photo = Photo.find params[:photo_id]
case params[:view]
when 'view1'
render ...view1
when 'view2'
render ...view2
when 'view3'
render ...view3
when 'view4'
render ...view4
end
...or...
2) use respond_to
def show
#photo = Photo.find params[:photo_id]
respond_to |view|
view.one {render ...view1}
view.two {render ...view2}
view.three {render ...view3}
view.four {render ...view4}
end
end
...or... something totally different??
You tell me?
I would call the view the same as params[:view], like such:
def show
#photo = Photo.find params[:photo_id]
render params[:view].to_sym
end
As long as you have view files that cover all possible parameters, that will work.
I have a helper which instantiates a model and renders a form. This form should be available to any view in the application
# support_form_helper
def support_form
#support_stats = SupportForm::Stat.find(get_stats_id)
#enquiry = SupportForm::Enquiry.new(stats_id: #support_stats.id)
render partial: 'support_form/enquiries/form'
end
And its rendered in the view:
# some_view.html.erb
<%= support_form %>
This is fine until I want to submit the form and validate it in the controller.
# enquiries_controller.rb
def create
#enquiry = SupportForm::Enquiry.new(params[:support_form_enquiry])
topic = #enquiry.topic
#stat = SupportForm::Stat.find(#enquiry.stats_id)
#stat.stats[topic] = #stat.stats[topic].to_i.next
respond_to do |format|
if #enquiry.valid? && #stat.save
format.html { redirect_to(root_path) }
else
format.html { redirect_to(:back) }
end
end
end
This is where I can't render the previous view with the errors attached to the invalid object. The helper gets invoked again and initializes a new #enquiries object, without the errors obviously.
How can I render the form in many views across an application and still return to the view with the object together with errors when it is invalid?
I found an answer which answers my question but its a bad idea:
Render the action that initiated update
def create
#enquiry = SupportForm::Enquiry.new(params[:support_form_enquiry])
topic = #enquiry.topic
#stat = SupportForm::Stat.find(#enquiry.stats_id)
#stat.stats[topic] = #stat.stats[topic].to_i.next
if #enquiry.valid? && #stat.save
redirect_to(root_path)
else
render Rails.application.routes.recognize_path(request.referer).values.join("/")
end
end
The problem is that there will likely be instance variables in the view that submitted the form and I would have to be able to instantiate all the instance variable in the application then.....not possible.
Currently I'm considering putting the errors in the flash hash... not something I want to do. With the original object returned i can repopulate the fields with the users input.
When you use redirect_to, rails will kick off a whole new controller & view sequence. Use
render "path/to/template/from/view/folder"`
instead.
A typical create action using this pattern would look like (for a 'post' object in this case):
def create
#post = Post.new(params[:post])
#created = #post.save
respond_to do |format|
if #created
flash[:notice] = 'Post was successfully created.'
format.html { redirect_to post_path(#post) }
format.js
else
format.html { render :action => :new }
format.js
end
end
end
Notice how if it's successfully created we do a full redirect to the "show" page for the post, but if it's not successful we just do a render.
You should probably modify your support_form helper so that it only creates a new #enquiry if it hasn't been created already:
def support_form
#support_stats = SupportForm::Stat.find(get_stats_id)
#enquiry ||= SupportForm::Enquiry.new(stats_id: #support_stats.id)
render partial: 'support_form/enquiries/form'
end
||= is shorthand for "equals itself or". If it hasn't been defined (or is nil or false) then it will fail the first part of the or and pass through to the second, where the object is created.
In your form partial, also, you should make sure you're using form_for, which will submit to the create or update action depending on whether the object has been saved already.
I have a controller "UserController" that should respond to normal and ajax requests to http://localhost:3000/user/3.
When it is a normal request, I want to render my view. When it is an AJAX request, I want to return JSON.
The correct approach seems to be a respond_to do |format| block. Writing the JSON is easy, but how can I get it to respond to the HTML and simply render the view as usual?
def show
#user = User.find(params[:id])
respond_to do |format|
format.html {
render :show ????this seems unnecessary. Can it be eliminated???
}
format.json {
render json: #user
}
end
end
As per my knowledge its not necessary to "render show" in format.html it will automatically look for a respective action view for ex : show.html.erb for html request and show,js,erb for JS request.
so this will work
respond_to do |format|
format.html # show.html.erb
format.json { render json: #user }
end
also, you can check the request is ajax or not by checking request.xhr? it returns true if request is a ajax one.
Yes, you can change it to
respond_to do |format|
format.html
format.json { render json: #user }
end
The best way to do this is just like Amitkumar Jha said, but if you need a simple and quick way to render your objects, you can also use this "shortcut":
def index
#users = User.all
respond_to :html, :json, :xml
end
Or make respond_to work for all the actions in the controller using respond_with :
class UserController < ApplicationController
respond_to :html, :json, :xml
def index
#users = User.all
respond_with(#users)
end
end
Starting from Rails 4.2 version you will need to use gem responder to be able to use respond_with.
If you need more control and want to be able to have a few actions that act differently, always use a full respond_to block. You can read more here.
I'm trying to have the "show" action for my pages controller render a Liquid template instead of the normal view. The template itself is stored in the database.
This is my show action:
def show
#organization = Organization.find_by_subdomain(request.subdomain)
#template = Liquid::Template.parse(Template.find(#organization.current_template))
#page = #organization.pages.find(params[:id])
respond_to do |format|
format.html { render #template.render('page' => #page)}
format.json { render json: #page }
end
end
However, it raises this exception:
uninitialized constant PagesController::Liquid
I'm a RoR newbie, so I'm assuming what's happening is that it's trying to find the Liquid class in the PagesController class, instead of realizing it's a class unto itself. I'm following the (somewhat sparse) instructions here as best I can.
What am I doing wrong?
You need to include liquid in your Gemfile:
gem "liquid"
Then run bundle install and restart your rails server.
Please consider the following method in a controller:
def get_navigation_from_session
respond_to do |format|
format.json { render json: session[:navigation]}
end
return session[:navigation]
end
What I want it to do is respond to an Ajax call and send the navigation hash if it's being asked for it. If not, I just want it to return the hash to the ruby code that needs it. This obviously isn't working. How can I fix the above method to accomplish this goal?
Thank you
# this is your action method, supposed to be called via your request cycle with rendering
def get_navigation_from_session
respond_to do |format|
format.json { render json: get_navigation_hash_from_session }
end
end
# a getter - maybe higher up in controller hiararchy
def get_navigation_hash_from_session
session[:navigation]
end