Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return url from paperclip to json

I have a rails app that consists of a CMS system that I use in order to enter sights from a city to my database. I am using paperclip to upload images to amazon s3. All is working fine. Now I want my json files that an ios app will use to include the urls of the images uploaded in s3. I have seen some answers here but I cannot seem to make my code work. What I have is this..

place model

attr_accessible :assets_attributes, :asset
has_many :assets
accepts_nested_attributes_for :assets, :allow_destroy => true

def avatar_url
   assets.map(&:asset_url)
end

asset model

class Asset < ActiveRecord::Base
  attr_accessible :asset_content_type, :asset_file_name, :asset_file_size, :asset_updated_at, :place_id, :asset
  belongs_to :place
  has_attached_file :asset

   validates_attachment :asset, :presence => true,
  :content_type => { :content_type => ['image/jpeg', 'image/png'] },
  :size => { :in => 0..1.megabytes }

def asset_url
    asset.url(:original)
    end

end

view code

<%= f.fields_for :assets do |asset_fields| %>

<% if asset_fields.object.new_record? %>
<p>
    <%= asset_fields.file_field :asset %>
</p>
<% end %>

<% end %>
<br/>

<%= f.fields_for :assets do |asset_fields| %>

<% unless asset_fields.object.new_record? %>


<%= link_to image_tag(asset_fields.object.asset.url(:original), :class => "style_image"), (asset_fields.object.asset.url(:original)) %>
    <%= asset_fields.check_box :_destroy %>

<% end %>

<% end %>

places controller

def index
    @places = Place.all
render :json => @places.to_json(:methods => [:avatar_url])
  end

Can anyone please help me?

like image 961
user3077352 Avatar asked Dec 07 '13 11:12

user3077352


1 Answers

In reference to the SO question you linked to (How can I get url for paperclip image in to_json), there are certain elements you'll need in order to get the image to render correctly

The problem you have is Paperclip's image method is actually an ActiveRecord object, and therefore you cannot just render it in a JSON request without doing some other stuff


The _url Method

The most important part of the process is to define the "_url" method in your asset model. This basically calls the .url function of Paperclip, allowing JSON to create the desired URL of the image on the fly (The url of the image is not an ActiveRecord object, and can therefore be sent via JSON)

As per the referenced SO question, you should put this action in your model:

#app/models/asset.rb
def asset_url
    asset.url(:medium)
end

Now when you render the JSON request in your controller, you can use this type of setup:

#app/controllers/places_controller.rb
render :json => @places.to_json(:methods => [:asset_url])

Because your asset model is an associate of places, this might not work straight away. However, it's definitely in the right direction, because I can remember doing this exact thing myself

The important thing to note here, is that you're actually passing the naked "URL" of the image through JSON, not the image object itself


Update

Here's an example from our video conference demo app we made:

#app/controllers/profiles_controller.rb
def update
   @profile = User.find(current_user.id)
   @profile.profile.update(upload_params)

   respond_to do |format|
      format.html { render :nothing => true }
      format.js   { render :partial => 'profiles/update.js' }
      format.json { render :json => @profile.profile.as_json(:only => [:id, :avatar], :methods => [:avatar_url])
      }
    end
end

   #app/models/profile.rb
   def avatar_url
       avatar.url(:original)
   end

So for you, I'd try this:

def index
    @places = Place.all
    render :json => @places.assets.as_json(:only => [:id, :asset], :methods => [:asset_url])
end

You could also try something like this:

#app/models/profile.rb
def avatar_url
   self.asset.avatar.url(:original)
end
like image 110
Richard Peck Avatar answered Oct 20 '22 19:10

Richard Peck