How to render params in view via JSON? - ruby-on-rails

I'm trying to render JSON to print the page. It's a method that it updates an attribute and render a view to print, like this:
class Admin::RequestsController < Admin::ApplicationController
def print
#request.print = 1
respond_to do |format|
if #request.save
format.json { render json: #request.as_json(only: [:id, :number]) }
end
end
authorize #request
end
end
This way, after clicking on the print icon, it opens a new window with options to print, but it lists nothing. Only [Object object].
I'm trying this to render print.json.builder to print, but it doesn't work:
json.(#request, :id, :number)
json.items do |json|
json.(#request.items, :item, :request_product)
end
I don't know if it's correct.

Why are you doing authorize #request at the end of your method?
Ruby implicitly returns whatever the last line of your method is, so you want your format.json method call to be the last thing you do. Could you move the authorize to be the first method call?
If it does need to be at the end, you can try this:
def print
#request.print = 1
result = nil
respond_to do |format|
if #request.save
result = format.json { render json: #request.as_json(only: [:id, :number]) }
end
end
authorize #request
result
end

Related

How to print multiple variable in Ruby controller?

I am totally new in ruby. My Ruby version 2.2. I have an edit profile form. I want to show both the table and form data in two different different place. Please check my code
users_controller.rb
def edit_profile
#user = User.get_profile(session[:user_id])
raise $user.inspect
respond_to do |format|
if params[:user][:avatar]
params[:user][:photo] = orginal_file_upload params[:user][:avatar]
end
raise params.inspect
if #user.update(user_params)
format.html { redirect_to :back, notice: 'Your profile was successfully updated.' }
format.json { render :show, status: :ok, location: #user }
else
format.html { render :my_profile }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
Here I have define raise $user.inspect and raise params.inspect I want to get both data. But here in my page only coming first one. Please check and let me know how to get my both array value.
Thank you.
raise is a mechanism of throwing errors. raise $user.to_s returns the control out of action. You can use puts method to display the values in controller.
The correct code will be:
def edit_profile
#user = User.get_profile(session[:user_id])
respond_to do |format|
if params[:user][:avatar]
params[:user][:photo] = orginal_file_upload params[:user][:avatar]
end
#user.update(user_params)
format.html { render :inline => "User<p> ID:<%= #user.id %><br>NAME: <%= #user.name %><br>EMAIL: <%= #user.email %></p>Params <p><%= params.inspect%></p>".html_safe }
end
end
Assign them to instance variables like #user and #params and access them in your views. Having said that you already have assigned #user variable and params is accessible in your views automatically.
# In your view
<%= #user.name %>
<%= params %>
Also, consider making your controller RESTful. You can send PUT request to your controllers URL (eg. PUT profile/1) it will automatically call your ProfileController#edit method.

How to save processed data in a rails model ( get NoMethodError )

I need to save processed data inside my model to render it as json but i get that the method is missing so time for a stupid question.
The model
class Post < ActiveRecord::Base
def self.html(html)
#html = html
end
end
The controller
# POST /posts
# POST /posts.json
def create
#post = Post.new(post_params)
respond_to do |format|
if #post.save
#post.html render_to_string(partial: 'post.html.erb', locals: { post: #post })
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json {
render :show,
status: :created,
location: #post
}
else
format.html { render :new }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
The error
NoMethodError - undefined method `html' for #<Post:0x0000000a5679d0>:
That's because in the builder i would like to output
json.extract! #post, :id, :content, :created_at, :updated_at, :html
I could probably do this in another way but now i'm curious, what am i missing?
Just add regular getter/setter:
class Post < ActiveRecord::Base
def html
#html
end
def html=(html)
#html = html
end
end
You also probably want an instance method, because you are working with instance of Post (you called Post.new earlier.
When you define the method html on the post model, you are creating a class method, and not an instance method. You need to remove the self and make it a setter by adding =:
class Post < ActiveRecord::Base
def html=(html)
#html = html
end
end

Different code in same controller action for html or json

I have a controller action that responds to the same root in two formats - html and json. But the code that runs for the html response is completely different than the one for the json response..
Now I have something like
def index
result_html = ...
result_json = ...
respond_to |format|
format.html
format.json { result = result_json.limit(10) }
end
end
and I would like to have it like
def index.html
result_html ...
end
and
def index.json
result_json ...
end
What would be the best way to organize it?
May be something like this will work for you.
def index
respond_to |format|
format.html { index_html}
format.json { index_json }
end
end
def index_html
...
end
def index_json
...
end
You can test for the format with request.format.symbol then when :json call your json action or when :html call your html action.

Rails: respond_to JSON and HTML

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.

Excluding some ActiveRecord properties from xml rendering in rails

I have an ActiveRecord model that I would like to convert to xml, but I do not want all the properties rendered in xml. Is there a parameter I can pass into the render method to keep a property from being rendered in xml?
Below is an example of what I am talking about.
def show
#person = Person.find(params[:id])
respond_to do |format|
format.xml { render :xml => #person }
end
end
produces the following xml
<person>
<name>Paul</name>
<age>25</age>
<phone>555.555.5555</phone>
</person>
However, I do not want the phone property to be shown. Is there some parameter in the render method that excludes properties from being rendered in xml? Kind of like the following example
def show
#person = Person.find(params[:id])
respond_to do |format|
format.xml { render :xml => #person, :exclude_attribute => :phone }
end
end
which would render the following xml
<person>
<name>Paul</name>
<age>25</age>
</person>
You can pass an array of model attribute names to the :only and :except options, so for your example it would be:
def show
#person = Person.find(params[:id])
respond_to do |format|
format.xml { render :text => #person.to_xml, :except => [:phone] }
end
end
to_xml documentation
I just was wondering this same thing, I made the change at the model level so I wouldn't have to do it in the controller, just another option if you are interested.
model
class Person < ActiveRecord::Base
def to_xml
super(:except => [:phone])
end
def to_json
super(:except => [:phone])
end
end
controller
class PeopleController < ApplicationController
# GET /people
# GET /people.xml
def index
#people = Person.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #people }
format.json { render :json => #people }
end
end
end
I set one of them up for json and xml on every object, kinda convenient when I want to filter things out of every alternative formatted response. The cool thing about this method is that even when you get a collection back, it will call this method and return the filtered results.
The "render :xml" did not work, but the to_xml did work. Below is an example
def show
#person = Person.find(params[:id])
respond_to do |format|
format.xml { render :text => #person.to_xml(:except => [:phone]) }
end
end
The except is good, but you have to remember to put it everywhere. If you're putting this in a controller, every method needs to have an except clause. I overwrite the serializable_hash method in my models to exclude what I don't want to show up. This has the benefits of not having t put it every place you're going to return as well as also applying to JSON responses.

Resources