Sending an image path in json response with paperclip in rails - ruby-on-rails

I am using paperclip for images in rails api.My problem is to send all ads which have also avatars along with other attributes.
I cant understand how I send all ads along with their images.
My response is like that
def ads_list
#ads = Ad.all.limit(10)
render json: {:success=>true, :message=>"List of all Ads",:ads=>#ads}, :status=>200
end
Through this all data send except avatars_urls.How I send avatar along with this?
My search till now.I found a solution for only one single object like this
Add in your model
def avatar_url
avatar.url(:medium)
end
and response is like that
render :json => #model.to_json(:only => [:id,:name,:homephone,:cellphone], :methods => [:avatar_url])
How I customize it for all objects or any other solutions?

I solve it
render json: {:success=>true, :message=>"List of all Ads",:ads=>#ads.map {|u| u.attributes.merge(:thumbnail_url => u.thumbnail.url)}}, :status=>200

Related

Update not working with id attribute Rails 4

I've got below URL with get attributes sending request to the controller:
http://localhost:3000/videos/new/save_video?video_id=16&status=200&id=PhTHHldZJJQ
Constoller:
def save_video
#video = Video.find(params[:video_id])
if params[:status].to_i == 200
#video.update(:yt_youtube_id => params[:id].to_s, :is_complete => true)
Video.delete_incomplete_videos
else
Video.delete_video(#video)
end
redirect_to videos_path, :notice => "video successfully uploaded"
end
However I'm getting this error somehow:
ActiveRecord::RecordNotFound at /videos/new/save_video
Couldn't find Video with id=PhTHHldZJJQ
Is there a reason why it's not finding from :video_id?
I cannot figure this out...
ActiveRecord ids are integers. You've passed in a string to find which won't convert to an integer, so it will always fail.
It seems that it is trying to search the video using :id and not :video_id. It is possibly another gem (like CanCan), which might be trying to load the video before the action starts, in a filter. Or it might be something else in the controller, can you post the full code of the controller?
If you just want this to work, use :id as the variable to send the video id, instead of :video_id.

RAILS3: to_JSON with multiple objects and includes

def list
#rings = Ring.order("RAND()")
#JSON RENDERING
render :json => #rings.to_json(:include => [:variations, :stones]), :callback => params[:callback]
end
def show
#showring = Ring.includes(:stones, :variations).find(params[:id])
#other_rings = Ring.select([:id, :stone_count]).where(:style_number => #showring.style_number).reject{ |ring| ring == #showring}
#JSON RENDERING
render :json => {#showring.to_json(:include =>[:variations, :stones]), :other_rings => #other_rings}, :callback => params[:callback]
end
My list view rendering works fine, but when i want to do a show view, with two objects, and showring with includes won't render proper JSON. It is quoting everything in the object with the includes...
JSON output looks like this:
showring => "{"available":"yes","eng...9","stone_y":"149.4"}]}"
other_rings => properly rendered object
On a seperate note, if i have already added the includes to #rings object, why do i then again have to add the association in the "to_json" method?
When you do
render :json => {:show_ring => #showring.to_json(:include =>[:variations, :stones]), :other_rings => #other_rings}
Rails is converting #showring to json (ie getting back a string representation), i.e. the value is the string literal. Instead do
render :json => {:show_ring => #showring.as_json(:include =>[:variations, :stones]), :other_rings => #other_rings}
as_json does all the work of turning the object into a hash but without the final step of turning into a string
if you are going to invest more time in building more JSON objects, you should look into a gem called rabl. It makes building JSON very simple, good for customization which then is good for building API.

Sending an image through JSON data

noobie here hope you guys don't mind! Im trying to query my user/id/pictures.json but all it returns are attributes cus i did a generic format.json {render :json => #photo.to_json()}. My question is how can i create and encapsulate the actual data from the images, so my client can turn that data in to an image? And also what do i need to create(attribute wise) besides the path of image(say you only had useless attributes eg: height content_type, description, thumbnail file_name)?
this is what im trying in my index.json.erb so far
}
<% #photos.each do |photo|%>
data: <%= StringIO.new(Base64.encode64(photo.public_filename(:large))) %>
<%end%>
}
i am getting back
{
data: #<StringIO:0x1058a6cd0>
}
which is not the IMGdata im looking for
looking for
Have a look at Data-URIs.
They essentially are Base64-encoded entities (documents) formatted as a URI
[{ "name":"red dot", "data": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="}, ...]
[UPDATE]
You need to read the file and encode it as Base64 (you also need to strip the newlines away in rails 2.3.x)
data = ActiveSupport::Base64.encode64(File.read("/images/image1.png")).gsub("\n", '')
uri = "data:image/png;base64,#{data}"
I think you are using Ruby on Rails, aren't you?
Then there are some steps needed to download an image (e.g. a png):
Create a mime type
Go to config/initializers/mime_types.rb and insert Mime::Type.register "image/png", :png at the end.
Create an image
For example, you could use the gem Chunky_PNG to create an image, see at http://rubygems.org/gems/chunky_png and https://github.com/wvanbergen/chunky_png/wiki
Prepare your controller
You have to tell your controller, that it can accept pngs. Modify your controller the following way
class UsersController < ApplicationController
respond_to :json, :png
def show
# your own stuff
# ...
respond_with(response) do |format|
format.json
format.png do
send_data ChunkyPNG::Image.new(width, height, ChunkyPNG::Color::TRANSPARENT), :type =>"image/png", :disposition => 'inline'
end
end
end
end
This will create a fully transparent image. If you want to draw something in this, look at the Chunky PNG docs.
It's up to the client how to render it really. This works for me, maybe worth a try.
render json: #thumbnail, type: :jpeg, content_type: 'image/jpeg'

How do you output JSON from Ruby on Rails?

I'm looking to have a model that gets created / updated via AJAX. How do you do this in Ruby on Rails?
Also, more specifically: how do you output JSON in RoR?
def create
response = {:success => false}
#source = Source.new(params[:source])
if #source.save
response.success = true
end
render :json => response.to_json
end
All you need to do is call render :json with an object, like so:
render :json => my_object
For most objects, this will just work. If it's an ActiveRecord object, make sure to look at as_json to see how that works. For your case illustrated above, your hash will be transformed to json and returned.
However, you do have an error: you cant access the success key via response.success -- you should instead do response[:success]
jimothy's solution is really good butI believe it isn't scalable in the long term. Rails is meant to be a model, view, and controller framework. Right now JSON is cheated out of a view in default rails. However there's a great project called RABL which allows JSON view. I've written up some arguments for why I think it's a good option and how to get up and running with it quickly. See if this is useful for you: http://blog.dcxn.com/2011/06/22/rails-json-templates-through-rabl/
#source = Source.new(params[:source])
respond_to do | f |
f.html {
# do stuff to populate your html view
# maybe nothing at all because #source is set
}
f.any(:xml, :json) {
render request.format.to_sym => #source
}
end

Filter a model's attributes before outputting as json

I need to output my model as json and everything is going fine. However, some of the attributes need to be 'beautified' by filtering them through some helper methods, such as number_to_human_size. How would I go about doing this?
In other words, say that I have an attribute named bytes and I want to pass it through number_to_human_size and have that result be output to json.
I would also like to 'trim' what gets output as json if that's possible, since I only need some of the attributes. Is this possible? Can someone please give me an example? I would really appreciate it.
Preliminary search results hint at something regarding as_json, but I can't find a tangible example pertaining to my situation. If this is really the solution, I would really appreciate an example.
Research: It seems I can use to_json's options to explicitly state which attributes I want, but I'm still in need of figuring out how to 'beautify' or 'filter' certain attributes by passing them through a helper before they're output as json.
Would I create a partial for a single json model, so _model.json.erb, and then create another one for the action I'm using, and within that simply render the partial with the collection of objects? Seems like a bunch of hoops to jump through. I'm wondering if there's a more direct/raw way of altering the json representation of a model.
Your model can override the as_json method, which Rails uses when rendering json:
# class.rb
include ActionView::Helpers::NumberHelper
class Item < ActiveRecord::Base
def as_json(options={})
{ :state => state, # just use the attribute when no helper is needed
:downloaded => number_to_human_size(downloaded)
}
end
end
Now you can call render :json in the controller:
#items = Item.all
# ... etc ...
format.json { render :json => #items }
Rails will call Item.as_json for each member of #items and return a JSON-encoded array.
I figured out a solution to this problem, but I don't know if it's the best. I would appreciate insight.
#items = Item.all
#response = []
#items.each do |item|
#response << {
:state => item.state,
:lock_status => item.lock_status,
:downloaded => ActionController::Base.helpers.number_to_human_size(item.downloaded),
:uploaded => ActionController::Base.helpers.number_to_human_size(item.uploaded),
:percent_complete => item.percent_complete,
:down_rate => ActionController::Base.helpers.number_to_human_size(item.down_rate),
:up_rate => ActionController::Base.helpers.number_to_human_size(item.up_rate),
:eta => item.eta
}
end
respond_to do |format|
format.json { render :json => #response }
end
Basically I construct a hash on the fly with the values I want and then render that instead. It's working, but like I said, I'm not sure if it's the best way.

Resources