Rails 5 - polymorphic attachment with dynamic styles using paperclip - ruby-on-rails

I am trying to have a polymorphic attachment class with dynamic styles using paperclip and use it form another class(Foo).
I have the Attachment class:
class Attachment < ApplicationRecord
belongs_to :attachable, polymorphic: true, optional: true
has_attached_file :attachment,
styles: ->(a) {a.instance.attachable.attachment_styles}
validates_attachment_content_type :attachment, content_type: /\Aimage\/.*\Z/
end
And the Foo class:
class Foo < ApplicationRecord
has_many :attachments, class_name: "Attachment", as: :attachable, dependent: :destroy
accepts_nested_attributes_for :attachments
def attachment_styles
{
:thumb => "30x30>",
:medium => "100x100>"
}
end
end
The problem here is that I don't have the foo object yet, inside that lambda function. a.instance.attachable returns nil.
The error I'm getting is:
NoMethodError: undefined method `attachment_styles' for nil:NilClass
I am using Rails 5 and paperclip 5.0.0.
I think this worked with Rails 4.
PS: I need the style to be dynamic because I will use the attachment from multiple models, not just from Foo.

Related

How to make a model has unlimited images with paperclip in Ruby on Rails?

I have a User model that has an avatar. Paperclip was used to allow image upload. However, I want a User to be able to upload as many images as possible (unlimited) . How do I modify my model to allow such behavior ?
The user model looks like this:
class Model < ApplicationRecord
has_attached_file :pic, styles: { medium: "420×633!", thumb: "100x100#" }, default_url: "/images/:style/missing.png"
validates_attachment_content_type :pic, content_type: /\Aimage\/.*\z/
has_many :reviews, dependent: :destroy
Thanks in advance !
You can store the photos (if you call it that) for a user in a separate model and add an association to it in User model:
Command line
rails g paperclip photo pic
app/models/user.rb
has_many :photos, dependent: :destroy
app/models/photo.rb
belongs_to :user
has_attached_file :pic, styles: { medium: "420×633!", thumb: "100x100#" }, default_url: "/images/:style/missing.png"
validates_attachment_content_type :pic, content_type: /\Aimage\/.*\z/
As per the given specifications you could generate another model for saving user_images, in this way user can have unlimited images.
user.rb
class User < ApplicationRecord
has_many :user_images, dependent: :destroy
accepts_nested_attributes :user_images
validates_attachment_content_type :pic, content_type: /\Aimage\/.*\z/
has_many :reviews, dependent: :destroy
end
user_image.rb
Class UserImage < ApplicationRecord
belongs_to :user
has_attached_file :user_image, styles: { medium: "420×633!", thumb: "100x100#" }, default_url: "/images/:style/missing.png"
end
Added accepts_nested_attributes in user_model and paperclip setting in user_image for uploading images.

Rails model with associated images and selecting main image for this model

I want to ask about, how can you properly select main image from association of images after you update main_image and delete more couple images etc.
I have this code:
It's the main model:
class Gallery < ApplicationRecord
has_many :paintings, inverse_of: :gallery
belongs_to :primary_painting, class_name: 'Painting', required: false
accepts_nested_attributes_for :paintings, reject_if: :all_blank, allow_destroy: true
before_validation :primary_painting_setup
private
def primary_painting_setup
self.primary_painting = paintings.any? ? paintings.select(&:primary?).first || paintings.first : nil
end
end
And this is associated model:
class Painting < ApplicationRecord
belongs_to :gallery, inverse_of: :paintings
has_attached_file :image, styles: { medium: '300x300>', thumb: '100x100>' }, default_url: '/images/:style/missing.png'
validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/
end
Basically, gallery has main_image on index page, which is chosen from associate paintings.
But f.e. if I delete all images and add a new one and set it as main image. It won't work, because on the stage of before_validation I have only old images, which aren't useful for me at all.
Of course I can use a helper or model method such as gallery.paintings.find(:&main_image_bool) every time I render a gallery, but it costs too much speed.
Can you advise more proper way to choose this? Maybe there's a magic association, that will help.

Paperclip separate styles

How can i separate styles for different models?
I have my Photo model which generate my styles
large:'300x300#',huge:'800x800'
also i have two models witch use this styles
Product
and
Post
so i want to use
large style only for Product
and huge style only for Post
product => has_many :photos
post => has_one :photo
photo => belongs_to :post
belongs_to :product
has_attached_file :image, :styles => {large:'300x300#',huge:'800x800'}
Is it possible?
I advice you to separte image by a image model type using STI, and polymorphism, therefore, add imageable_type, imageable_id, and type field to photo model, so:
app/models/photo.rb:
class Photo < AR::Base
belongs_to :imageable, polymorphic: true
end
app/models/photos/large_photo.rb:
class LargePhoto < Photo
has_attached_file :image, :styles => { large:'300x300#' }
end
app/models/photos/huge_photo.rb:
class HugePhoto < Photo
has_attached_file :image, :styles => { huge:'800x800' }
end
app/models/product.rb:
class Product < AR::Base
has_many :large_photos, as: imageable
end
app/models/post.rb:
class Post < AR::Base
has_one :huge_photo, as: imageable
end
BUT for me, will be better to use carrierwave, rather than paperclip for this case.

Image will not save with Paperclip and Rails 4

I'm trying to use Paperclip for uploading an image for an has many and belongs to relationship with 'pictures'
I'm certain that imagemagick etc, is correctly installed, because i've more image uploaders in this project that works, difference is that this one has an has many relation.
I'm not getting a 'Saving Attachment' in the console. So my idea is that this is completely ignored by the strong parameters.
In topicscontroller:
params.require(:topic).permit(:id, :title, :content, :active, pictures_attributes: [:image, :id, :_destroy] )
In Topic Model:
has_many :pictures, dependent: :destroy
accepts_nested_attributes_for :pictures, allow_destroy: true
validates :title, :content, presence: true
In Picture Model:
belongs_to :topic
has_attached_file :image,
:styles => { :medium => "400x400#", :thumb => "200x200#", :small => "50x50#" },
:default_url => ActionController::Base.helpers.asset_path('missing.png')
I know that there are many other topics about this, only all are rails 3 and is different in the way of setting 'attr_accessible'
With version 3.5.0 of Paperclip, everything is fine for Rails 4.

Nested forms dont work in rails_admin

Brand has many images is my association. Image uses paperclip
In Rails Admin, I want to add images when i add a brand
class Brand < ActiveRecord:Base
has_many :images, as=> :imageable
end
class Image < ActiveRecord:Base
attr_accessor :image_thumb
attr_accessible :image, :imageable_id, :imageable_type, :image_thumb
has_attached_file :image, :styles => { :medium => "300x300>", :thumb => "100x100>" }
belongs_to :imageable, :polymorphic => true
end
But this is what i get
How can i achieve my goal?
I need to add attr_accessible
class Brand < ActiveRecord::Base
attr_accessible :name, :images_attributes
has_many :products
has_many :images, :as => :imageable
accepts_nested_attributes_for :images, :allow_destroy => true
end
And solution is when you user acts_as_taggable, to add to your rails_admin.rb config file next code:
field :tag_list do
label "Tag"
end
Or 'image_list', depends on what you are use.

Resources