So I've been trying to fix this for a while now and I've had no luck in doing so. I have a model Posts that has_rich_text: body
class Post < ApplicationRecord
extend FriendlyId
friendly_id :title, use: :slugged
has_rich_text :body
has_rich_text :health_check
has_one_attached :cover_photo
has_many :post_tags, dependent: :destroy
has_many :tags, through: :post_tags
after_commit :add_default_cover, on: [:create, :update]
def add_default_cover
unless cover_photo.attached?
self.cover_photo.attach(io: File.open(Rails.root.join("app", "assets", "images", "default.png")), filename: 'default.png' , content_type: "image/png")
end
end
end
It works perfectly when I attach photos, but when ever I attach a gif it gets uploaded correctly into the edit/new screen and I can see the animation of the gif in the rich text editor. But as soon as I submit the edit/new form then a new variant is created as an image and that's what is being used when showing the post. When I check my storage system I find both the image and the gif versions.
Does anyone know why this is happening on submitting the form? I would want to upload a gif and display it without active stroage or action text changing it.
I had this same issue. I ended up hacking it on the client-side with JS.
My approach: on 'DOMContentLoaded' event for the page with the GIF/MP4s, I grab all the action text attachments, get their URLS, and then for the GIFs I replace the static image URL with the GIF URL, and for the MP4s I just create a new <video> element and give it the MP4 URL. It's not pretty, but it works.
Here is an example on my blog. Let me know if you find a better answer, this feels like something that should be built into action storage/text.
Related
I'm using Rails 5 with rails_admin and carrierwave gems.
I have a model Photo and and image uploader mounted on it (as per carrierwave documentation), looks roughly like this:
class Photo < ActiveRecord::Base
mount_uploader :image, ImageUploader
belongs_to :project
validates :name, presence: true
validates :image, presence: true
end
Given I have already some Photo objects created I can see a list of them in the rails_admin admin view.
And I start editing one of them
And I edit name
And I proceed to save it
Then rails admin fires some of it's magic and photo is being saved but after this action the image dissapears.
I have been digging a little in what request are being fired and rails_admin fires a PUT request with such params:
{
"authenticity_token"=>"xxx",
"photo"=>{
"name"=>"test2",
"description"=>"ewdeeweeefxxxwefwe",
"project_id"=>"3",
"image_cache"=>"",
"main"=>"0",
"about_us"=>"0"
},
"return_to"=>"http://localhost:3000/panel-admin/photo?model_name=photo", "_save"=>"", "model_name"=>"photo", "id"=>"29"}
and my Photo object is being update with not only name but also with image_url that of course overrides Image that already was mounted to the Photo
I have no idea why this is happening and how to prevent it.
Anyone might have encountered this issue and knows how to resolve it?
I found that. When I uncomment my custom filename method in uploader, it works well.
I'm currently building an app which has a model Post. I'm using the paperclip gem to upload images, and everything is going well.
class Post < ActiveRecord::Base
has_attached_file :headerimage, styles: {banner => "400x300#"}
end
As you can see by my class above, if I were to get a Post object, I could get the banner image with the following in my view:
image = Post.first.headerimage(:banner)
Alias
However, in my app, it must have the image attribute image refer to the thumbnail image. So, in my models class, I wrote
class Post < ActiveRecord::Base
has_attached_file :headerimage, styles: {banner => "400x300#"}
alias_attribute :image, :headerimage
end
which allows me to get an image by calling the following:
image = Post.first.image
This is what I want - however, it gets the original image from paperclip, so it is equivalent to writing the following:
image = Post.first.headerimage instead of image = Post.first.headerimage(:banner)
How can I set up a proper alias_attribute to access the paperclip thumnail? I can't seem to find an answer anywhere else, and I am unsure how paperclip is actually working.
I thought I might logically be able to do something like
alias_attribute :image, :headerimage(:banner)
but that does not work.
You can just try this - basically call the original with arguments since aliases won't take parameter but we know the fixed parameter to pass:
alias :image, :headerimage
def headerimage(name=nil)
headerimage(name || :thumb)
end
I'm attempting to install CarrierWave gem on ActiveAdmin in rails, and the setup seemed easy enough. However, when I attempt to upload a test image to the /public/uploads directory, the image isn't saved. What's more irritating is the fact that there is no exception being raised, so I don't know where to look in order to find the issue. I can create a post, browse for an image, select that image, and submit the post in order to be saved, but I still end up with IMAGE: EMPTY on the show page in ActiveAdmin as shown below. In the image, I wrote a lorem ipsum post that included an image, and I saved it.
How to I actually get the uploader to upload?
ruby 1.9.3p547 (2014-05-14 revision 45962) [x86_64-darwin10.8.0]
Rails 4.1.6
This is the show page for a single Post object within ActiveAdmin
This is a full page screenshot of the form in question
The same form, but zoomed in. Obviously, I wasn't trying to upload an image in this screenshot.
/app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
storage :file
def store_dir
"public/uploads"
end
end
/app/models/post.rb
class Post < ActiveRecord::Base
belongs_to :category
scope :rails, -> { where(category_id: 1) }
extend FriendlyId
friendly_id :title, use: [:slugged, :finders]
mount_uploader :image, ImageUploader
end
After a couple more hours of searching, I found the inspiration for an answer in another question, which you can find here.
The reason I wasn't getting a result at all was because I had not permitted the application to accept an :image in the app/admin/post.rb file. Now, I still don't know why there was no error raised (or even a line logged to the console), but fixing the problem of getting an upload is as simple as permitting the upload parameter as follows:
permit_params :title, :slug, :blurb, :content, :category_id, :image
When I posted this question, I had not added in that last :image, so my application was simply throwing away that parameter instead of saving it within the file system with the rest of the post.
My conundrum is how to embed in an html page an image whose source is not available to the Internet at large.
Let's say I have, in a Rails/Paperclip setup, the following model:
class Figure < ActiveRecord::Base
has_attached_file :image
...
end
class User < ActiveRecord::Base
... (authentication code here)
has_many :figures
end
In the controller:
class FiguresController < ActionController::Base
def show
# users must be authenticated, and they can only access their own figures
#figure = current_user.figures.find(params[:id])
end
end
In the view:
<%= image_tag(#figure.image.url) %>
The problem with this, of course, is that with the default Paperclip settings images are stored in the public directory, and anyone with the link can access the stored image bypassing authentication/authorization.
Now, if we tell Paperclip to store attachments at a private locations:
class Figure < ActiveRecord::Base
has_attached_file :image, path: ":rails_root/private/:class/:attachment/:id_partition/:style/:filename",
url: ":rails_root/private/:class/:attachment/:id_partition/:style/:filename"
...
end
Then it's easy to control who the image gets served to:
class FiguresController < ActionController::Base
def show
#figure = current_user.figures.find(params[:id])
send_file #figure.image.path, type: 'image/jpeg', disposition: 'inline'
end
end
The effect of this action is to display the image in its own browser window/tab.
On the other hand, image_tag(#figure.image.url) will understandably produce a routing error, because the source cannot be accessed!
Thus, is there a way to display the image via image_tag in a regular HTML page, while still restricting access to it?
You need to change the :url option passed to has_attached_file so that it matches the route for your figures controller.
For example, if the correct url is /figures/123 for the figure with is 123 then the url you pass to has_attached_file should be
'/figures/:id'
Or even
'/:class/:id'
Since the :class segment will be interpolated to the pluralized lowercase underscore form of the name. You could also append the extension or the filename if you wanted (but you would then have to change the controller code slightly to extract the id)
I have a project using Paperclip gem for attachments and Globalize3 for attribute translation. Records need to have a different attachment for each locale.
I though about moving Paperclip attributes to translation table, and that might work, but I don't think that would work when Paperclip needs to delete attachments.
What's the best way to achieve something like that?
UPDATE: to be clear, I want this because my client wants to upload different images for each locale.
Unfortunately I didn't find a way to do this using Globalize3. In theory, I could have added a separate model for image and add image_id to list of translated columns (to have something like MainModel -> Translation -> Image), but it seems that Globalize has some migration issues with non-string columns.
Instead of using Globalize3, I did this with a separate Image model with locale attribute and main model which accepts nested attributes for it. Something along the lines of:
class MainModel < ActiveRecord::Base
has_many :main_model_images
accepts_nested_attributes_for :main_model_images
# return image for locale or any other as a fallback
def localized_image(locale)
promo_box_images.where(:locale => locale).first || promo_box_images.first
end
end
class MainModelImage < ActiveRecord::Base
belongs_to :main_model
has_attached_file :image
validates :locale,
:presence => true,
:uniqueness => { :scope => :main_model_id }
end
Tricky part was getting form to accept nested attributes only for one image, instead of all images in has_many relation.
=f.fields_for :main_model_images, #main_model.image_for_locale(I18n.locale) do |f_image|
=f_image.hidden_field :locale
=f_image.label :image
You could also try the paperclip-globalize3 gem, it should handle the case you describe. https://github.com/emjot/paperclip-globalize3
Ok since you asked me to share my solution to this problem even though I am using Carrierwave as a library for uploading here is it:
Ok so I would have a model setup like this:
class MyModel < ActiveRecord::Base
# ...
translates :attr_one, :attr_two, :uploaded_file
Now what I need for CarrierWave to work is place to attach the uploader to and that can be done on the Translation model
Translation.mount_uploader :uploaded_file, FileUploader
end
Now for your question about deleting, I think though I haven't needed to do it but it should work as the README says it should but on the translation model. https://github.com/jnicklas/carrierwave#removing-uploaded-files
MyModel.first.translation.remove_uploaded_file!
I haven't taken a look at paperclip for a good 2 years and if this is not applicable knowledge I suggest you try out carrierwave.