Understanding how carrierwave implements image uploading
public folder used to hold static files!
localhost:3000/404 you will see that
page renders immediately, Rails does not need to process it and serve it (no database lookups
or route lookups)public, you can create a file that will store the images for your model!Book model:
cd public && mkdir bookspublic/books/2/public/books/2/cover,
public/books/2/back, public/books/2/author<%= image_tag "/books/#{@book.id}/cover/cover.jpg" %>edit page:
<%= f.file_field :db_name %>attr_accessor for the database name field!after_save :save_cover_image, if: :cover callback: which allows us to take the file
that was uploaded and save it to the public directory!class Book
  after_save :save_cover_image, if: :cover
  
  def save_cover_image
    filename = cover.original_filename #given by the file upload
    folder = "public/books/#{id}/cover"
    
    FileUtils::mkdir_p folder # generates the given folder path rather then checking to see
                              # if each path exists one by one
                              
    f = File.open File.join(folder, filename), "wb"
    f.write cover.read()
    f.close
    
    self.cover = nil
    update cover_filename: filename # cover_filename is the actual database name in the books table
  
  end
end
The above code creates an attribute reader and writer method called cover.
The object has a database field called cover_filename (which is a string).
After an object has created or updated, the after_save callback is used to store the file in your
rails app (within the public directory), then the object has its cover_filename attribute updated
Then you can edit the show page:
<%= image_tag "/books/#{@book.id}/cover/#{@book.cover_filename}" if @book.cover_filename? %>
gem 'carrierwave', ~> 0.10.0bundle installrails g uploader Cover (Cover for example)mount_uploader :cover, CoverUploader<%= modelclass.file_field :cover %><%= image_tag(@post.image.url, alt: 'Image') if @post.image? %>include Carrierwave::MiniMagick
resize_to_fill method option:
process resize_to_fill: [200, 100], for exampleresize_to_limit, resize_to_fill, resize_to_fit# Create different versions of your uploaded files:
version :optimised do
  process convert: 'webp'
  process :set_content_type_to_webp
  def full_filename(for_file = model.file_name.file)
    extension = File.extname(for_file)
    "#{for_file.sub(extension, '.webp')}"
  end
  def exists?
    file&.exists?
  end
end
protected
# Required to actually force Amazon S3 to treat it like an image
def set_content_type_to_webp
  file.instance_variable_set(:@content_type, 'image/webp')
end
instance = MyUploader.new
instance.recreate_versions!(:thumb)
has_many of Model Bbelongs_to Model A# in model_a.rb
has_many :model_bs
accepts_nested_attributes_for :model_bs 
# make sure this is plural
# -------------------------------------------
# in model_b.rb
belongs_to :model_a
mount_uploader .... # used for carrierwave
# make sure that this model has a db field named after the uploader
# t.references :model_a # singular!!!
# -------------------------------------------
# in model_a_controller.rb
def new
  @modela = ModelA.new
  @modela.modelbs.build
end
def create
  # normal stuff
end
private
def modela_params
  params.require().permit(model_bs_attributes: [database names for model b])
  # MUST BE PLURAL model_bS_attributeS: []
end
# -------------------------------------------
# in the form for creating this new model
<%= form_for ....
  #...other code
  <%= f.fields_for :model_bs do |ff| %>
    <%= ff.label ...%>
    <%= ff.file_field :uploader, multiple: true, name: "model_a[model_b_attributes][][uploader]" %>
  <% end %>
<% end %>