gem Paperclip interpolation - ruby-on-rails

Good day.
I have rails 3.1. and gem Paperclip
in my application to manage companies contracts:
MODEL
model/contract.rb
has_many :contract_files
model/contract_file.rb
has_attached_file :data
CONSOLE
Loading development environment (Rails 3.1.0)
1.9.2p290 :001 > cont = Contract.first
Contract Load (0.1ms) SELECT "contracts".* FROM "contracts" LIMIT 1
=> #Contract id: 1, organization: "Com.org", and etc ....
1.9.2p290 :002 > cont.contract_files
ContractFile Load (0.2ms) SELECT "contract_files".* FROM "contract_files"
WHERE "contract_files"."contract_id" = 1
=> #[ContractFile id: 88, caption: "asdf", and etc ...]
QUESTION
Be kind, tell me please, how can I extract Contract id: 1 in
model/contract_files.rb
has_attached_file :data,
:url => "/assets/paperclip/:contract_id/:filename"
EXAMPLE WHAT I WANT TO GET
On http//localhost:3000/contracts/1 get such files pathes:
http//localhost:3000/contracts/1/assets/paperclip/1/XXX.pdf
http//localhost:3000/contracts/1/assets/paperclip/1/XXY.pdf
http//localhost:3000/contracts/1/assets/paperclip/1/XXZ.pdf
Thanks a lot for helping.

If I get it clear you might do it this way:
Contract.find( params[:id] ).contract_files.map { |cf| cf.data.url }
# Dont't forget to handle nonexistent id
Upd
To place contract_id in url you should recover default paperclip :url and :path parameters this way:
#model/contract_file.rb
has_attached_file :data, :path => "public/contracts/:parent_id/assets/paperclip/:id.:extension", :url => "/contracts/:parent_id/assets/paperclip/:id.:extension"
Paperclip.interpolates :parent_id do |a, s|
a.instance.contract.id
end

Related

Issues with Globalize and CarrierWave uploads in Rails 4.2 app

I have issues with translated files in my Rails 4.2 app.
Background
Here are the gem versions I'm using:
gem "rails", "4.2.1"
gem "carrierwave" # 0.10.0
gem "globalize" # 5.0.1
And my model:
class Download < ActiveRecord::Base
belongs_to :download_type
has_and_belongs_to_many :products
translates :title, :part_number, :file
mount_uploader :file, DownloadFileUploader
validates :title, presence: true
def to_param
"#{id}-#{title.parameterize}"
end
end
The Issues
In my view, I want to list a Download and all of the current translations for that download, but all I get is the current locale data for each translation. In the Rails console:
> I18n.locale
=> :en
> download = Download.find(481)
=> #<Download id: 481, title: "SmartSensor HD Quick-reference Guide (User)", part_number: "WX-500-0171", download_type_id: 3, created_at: "2015-01-16 22:49:13", updated_at: "2015-04-20 16:59:25", file: "smartsensor_hd_user_quick-reference_guide-20150116...", download_updated_at: nil>
> download.translations.count
=> 8
> download.translated_locales
=> [:de, :en, :es, :fr, :it, :pt, :ru, :"zh-CN"]
> download.file.class
=> DownloadFileUploader
> download.file.url
=> "/uploads/download/file/481/smartsensor_hd_user_quick-reference_guide-20150116154913-en.pdf"
> download.title
=> "SmartSensor HD Quick-reference Guide (User)"
> download.part_number
=> "WX-500-0171"
And when the locale changes:
> I18n.locale = :de
=> :de
> download.file.class
=> DownloadFileUploader
> download.file.url
=> "/uploads/download/file/481/smartsensor_hd_user_quick-reference_guide-20150116154913-en.pdf"
> download.title
=> "SmartSensor HD Kurzanleitung"
> download.part_number
=> "WX-502-0006"
If I try and access the translation directly:
> I18n.locale = :de
=> :de
> download.translation.file.class
=> String
If I change how the uploader is mounted in my model:
Translation.mount_uploader :file, DownloadFileUploader
Existing translations list correctly—including the file, but I can no longer upload files. What gets stored in the database is this:
/uploads/download/translation/file/401/%23%3CActionDispatch%3A%3AHttp%3A%3AUploadedFile%3A0x007f9c12e6fe00%3E
Notice that it inserts /translation into the path, which I can fix in the uploader, but the filename isn't actually a file.
If I move translates :title, :part_number, :file below mount_uploader :file, DownloadFileUploader in my model, Globalize overrides the mounted uploader and that column is returned as class String when accessing it.
The Cry for Help
Help! 😮
I wrote this simple gem https://github.com/dalpo/carrierwave_globalize. which it should allow to use Globalize and Carrierwave together.
You have to extend your model with the CarrierwaveGlobalize module and use the mount_translated_uploader class method to mount your carrierwave uploader instead of the mount_uploader mehtod.
Follow the instructions in the readme for more info.
Old question, but... do not use Globalize with CarrierWave on the same attribute, they both make overrides for the default behavior.
You can do this in your model:
class Download < ActiveRecord::Base
belongs_to :download_type
has_and_belongs_to_many :products
translates :title, :part_number
mount_uploader :file, DownloadFileUploader
validates :title, presence: true
def to_param
"#{id}-#{title.parameterize}"
end
end
And then override file storing for your uploader in system to use I18n.locale:
def store_dir
"uploads/#{I18n.locale}/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end

Paperclip doesn't store in a proper format fetched image by url

When I trying to fetch a facebook image by the graph URL(https://graph.facebook.com), paperclip stores avatar_image_name as "picture" in the database. The example of code:
img = UserImages.new
img.avatar = URI.parse('https://graph.facebook.com/666980153384194/picture?type=large')
img.save
The MySQL query in a console log:
=> #<URI::HTTPS:0x00000009954490 URL:https://graph.facebook.com/666980153384194/picture?type=large>
irb(main):009:0> img.save
(0.0ms) BEGIN
SQL (0.0ms) INSERT INTO `user_images` (`avatar_content_type`, `avatar_file_name`, `avatar_file_size`, `avatar_updated
_at`, `created_at`, `updated_at`) VALUES ('image/jpeg', 'picture', 6157, '2014-07-08 13:55:53', '2014-07-08 13:56:02', '
2014-07-08 13:56:02')
(29.1ms) COMMIT
As you can see fetched image file stored by the name 'picture'. But if to fetch image by Direct URL like:
https://scontent-a-lax.xx.fbcdn.net/hphotos-prn2/v/t1.0-9/10478546_662150043867205_2640371404472615909_n.jpg?oh=cb2fe9d421fef3d7d2220bb48a2a36e2&oe=5418E8FB
The fetched image stored as:
(0.0ms) BEGIN
Command :: file -b --mime "C:/Users/Windows/AppData/Local/Temp/f1620d075c0642a77f7b98e532d8a8eb20140708-1040-1h5z4e6.jpg
"
SQL (1.0ms) INSERT INTO `user_images` (`avatar_content_type`, `avatar_file_name`, `avatar_file_size`, `avatar_updated
_at`, `created_at`, `updated_at`) VALUES ('image/jpeg', '10478546_662150043867205_2640371404472615909_n.jpg', 25862, '20
14-07-08 14:02:45', '2014-07-08 14:02:49', '2014-07-08 14:02:49')
(34.1ms) COMMIT
=> true
Any advise(solution) will be highly appreciated.
The source of UserImages class:
class UserImages < ActiveRecord::Base
belongs_to :imageable ,polymorphic: true
has_attached_file :avatar,
:styles => { :medium => "300x300>", :thumb => "125x125>" },
:path => ":rails_root/public/images/users/:id/:style/:hash.:extension",
:default_url => "/images/normal/missing.jpg",
:url => "/images/users/:id/:style/:hash.:extension",
:hash_secret => "EWRWerrew234UTY"
validates_attachment :avatar, :content_type => { :content_type => ["image/jpeg", "image/gif", "image/png"] },
:size => { :in => 0..5.megabytes }
end
There is no problem in both fetching URLs.... Both working fine...
The difference is only because paperclip generates the file name from the last part of the URL...
So in the first URL
https://graph.facebook.com/666980153384194/picture?type=large
And in the second URL
https://scontent-a-lax.xx.fbcdn.net/hphotos-prn2/v/t1.0-9/10478546_662150043867205_2640371404472615909_n.jpg?oh=cb2fe9d421fef3d7d2220bb48a2a36e2&oe=5418E8FB
I've bolded the part of the URL that paperclip is using to generate filename.... And in both cases you shouldn't really bother yourself with the file name... Since you can do any operation you want thought paperclip.
And you can make sure that the files are uploaded by checking the path public/images/users/:id (the paperclip path configuration)

Cloudinary URLs break with Mongoid 3?

I've using the Cloudinary gem, which up until now has worked fine as an embedded Photo model in Mongoid:
class PhotoUploader < CarrierWave::Uploader::Base
include Cloudinary::CarrierWave
def public_id
return model.id
end
end
class Photo
include Mongoid::Document
include Mongoid::Timestamps
embedded_in :place#, :inverse_of => :photos, :autosave => true
mount_uploader :image, PhotoUploader
#...
end
However, after upgrading to Mongoid 3, getting the image URL no longer works. Consider this Photo model:
1.9.3p194 :019 > p
=> #<Photo _id: 507bc3c82a450b14bd00e00a, _type: nil, created_at: 2012-10-15 08:05:28 UTC, updated_at: 2012-10-15 08:05:28 UTC, image_filename: nil, caption: nil, original_url: "http://www.reactionny.com//images/assets/101755_316529.JPG", image: "v1350288333/507bc3c82a450b14bd00e00a.jpg">
1.9.3p194 :020 > p.image
=> /assets/fallback/default.png
1.9.3p194 :021 > p.image_url
=> "/assets/fallback/default.png"
1.9.3p194 :022 > p['image']
=> "v1350288333/507bc3c82a450b14bd00e00a.jpg"
Why is it no longer returning the fully-qualified Cloudinary URL, in the form http://res.cloudinary.com/XXXXXX/image/upload/v1350288842/507bc5ca2a450b14bd00e896.jpg?
It seems that carrierwave-mongoid changed the name of the field in which the image is saved from yyy to yyy_filename.
In your model inspection printing you can see that image_filename is nil.
The integration with the Cloudinary GEM and CarrierWave seems to be working fine, but you need to migrate your model.
The relevant field used to be called 'image' and it's now called 'image_filename'. You should probably update your model to use the new field name and copy all values.
Another possible solution would be to specifically set the attribute name using mount_on:
mount_uploader :image, PhotoUploader, mount_on: :image

Ruby add_item for eBay

I am attempting to write a ruby on rails app that posts an item to eBay. Cody Fauser/Garry Tan have a gem called ebayApi which is built on top of the ebay gem. When I attempt to post an item, I am getting an error back from ebay that says the condition ID is required for this category. I have found a category that does not require the condition, and I can post to that category. Searching through the eBay API documentation, I have found a tag conditionID under the "item" class. However, in the documentation for ebayAPI, there is no such tag. Looking back at the ebay API documentation, there is an older way to specify condition, using lookup_attributes. I have noted that the return xml is coming in API version 745, and Garry Gan's updated of the ruby interface is running version 609. I have tried using the lookup, and seem to get the same error (condition required). I am using the following code to specify the item:
#ebay = Ebay::Api.new :auth_token => #seller.ebay_token
item = Ebay::Types::Item.new( :primary_category => Ebay::Types::Category.new(:category_id => #ebayTemplate.categoryID),
:title => #ebayTemplate.name,
:description => #ebayTemplate.description,
:location => #ebayTemplate.location,
:start_price => Money.new((#ebayTemplate.startPrice*100).to_d, #ebayTemplate.currency),
:quantity => 1,
:listing_duration => #ebayTemplate.listingDuration,
:country => #ebayTemplate.country,
:currency => #ebayTemplate.currency,
:payment_methods => ['VisaMC', 'PayPal'],
:paypal_email_address => '********#gmail.com',
:dispatch_time_max => 3,
:lookup_attributes => [Ebay::Types::LookupAttribute.new( :name => "Condition", :value => "New")],
# :attribute_sets => [
# Ebay::Types::AttributeSet.new(
# :attribute_set_id => 2919,
# :attributes => [
# Ebay::Types::Attribute.new(
# :attribute_id => 10244,
# :values => [ Ebay::Types::Val.new(:value_id => 10425) ]
# )
# ]
# )
# ],
:shipping_details => Ebay::Types::ShippingDetails.new(
:shipping_service_options => [
# ShippingServiceOptions.new(
# :shipping_service_priority => 2, # Display priority in the listing
# :shipping_service => 'UPSNextDay',
# :shipping_service_cost => Money.new(1000, 'USD'),
# :shipping_surcharge => Money.new(299, 'USD')
# ),
Ebay::Types::ShippingServiceOptions.new(
:shipping_service_priority => 1, # Display priority in the listing
:shipping_service => #ebayTemplate.shipSvc,
:shipping_service_cost => Money.new((#ebayTemplate.shipSvcCost*100).to_d, #ebayTemplate.currency),
:shipping_surcharge => Money.new((#ebayTemplate.shipSurcharge*100).to_d, #ebayTemplate.currency)
)
],
:international_shipping_service_options => [
Ebay::Types::InternationalShippingServiceOptions.new(
:shipping_service => 'USPSPriorityMailInternational',
:shipping_service_cost => Money.new((#ebayTemplate.shipSvcCost*100).to_d, #ebayTemplate.currency),
:shipping_service_priority => 2,
:ship_to_location => #ebayTemplate.shipToLocation
)
]
),
:return_policy => Ebay::Types::ReturnPolicy.new (
:description => 'this product for suckers only!',
:returns_accepted_option => 'ReturnsAccepted'
)
#:condition_id => 1000
)
#response = #ebay.add_item(:item => item)
As you can see, it is just a mutation of the example given by Cody Fauser. The condition_id at the bottom will bring up an error as there is no such attribute. It seems to me there is no facility for this in the gem since the requirement came into existence after the gem was created. I have not been able to find any other gems to connect with ebay. I have also noticed, there are very little complaints about this even though people are still downloading the gem (10 people downloaded it today). I think there are quite a number of people writing for ebay. Is there a key word I am missing to specify the condition? A work around that people have been using? Another gem I have missed?
There is an existing item_conditions_codes.rb in the gem's type directory and only has two values New and Used. Guess you could add more values in there. However still needs mapping to ID's per the updating (and changed from Attributes) method
You have to modify in the gem library in .. ruby/1.8/gems/ebayapi-0.12.0/lib/ebay/types/item.rb
and add the following new lines
# added to allow ConditionID to be pushed into XML
numeric_node :condition_id, 'ConditionID', :optional => true
then in your ruby ebay code use the following convention
:condition_id => 1500,
At least that seems to work for me right now.

Feedzirra in Rails 3

I am trying to get feedzirra running on rails 3, I tried by some methods I have found on the internet.
This is in my gemfile:
source 'http://gems.github.com'
gem 'loofah', '1.0.0.beta.1'
group :after_initialize do
gem 'pauldix-feedzirra'
end
And i've out this after bundle.setup in root.rb
Bundler.require :after_initialize
And this is the code in my model (movie.rb)
class Movie < ActiveRecord::Base
def self.import_from_feed
feed = Feedzirra::Feed.fetch_and_parse("url-to.xml")
add_entries(feed.entries)
end
private
def self.add_entries(entries)
entries.each do |entry|
unless exists? :guid => entry.id
create!(
:title => entry.title,
:synopsis => entry.synopsis,
:cover => entry.cover,
:duration => entry.duration,
:channel => entry.channel,
:imdb_rating => entry.imdb_rating,
:imdb_votes => entry.imdb_votes,
:imdb_id => entry.imdb_votes
)
end
end
end
end
I try to run the import_from_feed function from the console and I keep getting this error:
>> Movie.import_from_feed
NameError: uninitialized constant Movie::Feedzirra
from /Users/myname/Ruby/appname/app/models/movie.rb:3:in `import_from_feed'
from (irb):1
Can someone help me out? Been trying for ages now!
Two things:
Just add the gem, not under :after_initialize
Use the feedzirra gem, not the old pauldix-feedzirra one.

Resources