my plan is i want to create a model only for images and use that model to create profile pictures, gallery etc..
so, i have created a separate model for images and i was able to store images in display those images. but, they are too big and so i want to create a thumbnail version.
my configuration is
class Image < ActiveRecord::Base
mount_uploader :avatar, AvatarUploader
end
controller:
class ImagesController < ApplicationController
def new
#image_upload=Image.new
end
def create
#image_upload=Image.create(uploading_image)
if #image_upload.save
redirect_to '/users'
end
end
def uploading_image
params.require(:image).permit(:avatar)
end
end
uploader:
class AvatarUploader < CarrierWave::Uploader::Base
include CarrierWave::RMagick
storage :file
def store_dir
"uploads/#{model.class.to_s.underscore}...(default store only)"
end
version :thumb do
process :resize_to_limit => [50, 50]
end
user controller:
def index
#user_profile=Profile.find(1)
#imagefile=Image.first
end
users/index.html.erb:
<%= image_tag #imagefile.avatar.to_s %> #This gives me the whole image.
<%= image_tag #imagefile.image_url(:thumb).to_s %> #says undefined method `image_url' for #<Image:0x007f6cd0538010>
ps: i can see a thumbnail version in the folder
It would be so great, if anyone could help me out.
You call your other versions of the #imagefile the same way you call its original copy, just add the version name. And you can use the url helper. so:
<%= image_tag #imagefile.avatar.url %>
<%= image_tag #imagefile.avatar.thumb.url %>
<%= image_tag #imagefile.image_url(:thumb) %> should be <%= image_tag #imagefile.avatar_url(:thumb) %> as the field that has an uploader mounted is called 'avatar'. Also you shouldn't need to call .to_s on the url.
Related
I used Carrierwave to upload images to polymorphic table.
With the following codes , I can upload and display the images correctly.
But now I want to auto upload and display image after choose a image in new.html.erb. In other words , I want to run
Attachment.create(:attachment => params[:attachment], :attachmentable =>#img) if params[:attachment]
before img create action, just after I choose a image.
What should I do with the codes? Thank you so much for giving me guidances.
Part of my codes as follows:
My Gemfiles :
gem 'rails', '~> 5.2'
gem 'carrierwave', '~> 1.2', '>= 1.2.2'
gem 'mini_magick'
My img.rb:
class Img < ActiveRecord::Base
has_many :attachments, as: :attachmentable, :dependent => :destroy
end
My models of attachment.rb:
class Attachment < ApplicationRecord
mount_uploader :attachment, ImageUploader
belongs_to :attachmentable, :polymorphic => true
end
My controller of imgs_controller
class ImgsController < ApplicationController
def index
#imgs = Img.all
end
def show
#img = Img.find(params[:id])
end
def new
#img = Img.new
end
def create
#img = Img.new(img_params)
if #img.save
Attachment.create(:attachment => params[:attachment], :attachmentable =>#img) if params[:attachment]
redirect_to #img
end
end
def destroy
#img = Img.find(params[:id])
#img.destroy
redirect_to #img
end
private
def img_params
params.require(:img).permit(:img_name)
end
end
My html of imgs
# new.html.erb
<%= form_for(#img,:html => {:multipart => true}) do |f| %>
<%= f.text_field :img_name %>
<%= file_field_tag :attachment %>
<%= f.submit "upload" %>
<% end %>
# show.html.erb
<% #img.attachments.each do |f| %>
<%= image_tag f.attachment.url %>
<% end %>
As per the description mentioned in the post you want that as soon as the user browses the image from location you want that image to be uploaded to cloud storage using carrierwave.
One way of doing this would be making an ajax call to the controller after the user has completed the browsing of image from his system and remotely uploading the image to cloud.
Unnecessary:
But what happens if user keeps on changing the image while browsing, will you uploading each image browsed irrespective of the fact that you would not be showing that image or will be needing it.
Workaround:
You can use jquery to the read the image browsed and then show the image to the user if needed and when the form is submitted then only you upload the image to cloud storage.
I'm currently implementing CarrierWave into my app. A problem I noticed is that most images I've uploaded fail to correctly generate a thumbnail size (64x64).
I'm using resize_to_fit and resize_to_fill for different versions, and the resize_to_fill (for cropping) is failing most of the time.
Here I've generated two versions, gallery and thumb.
// image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
storage :file
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
version :gallery do
process resize_to_fit: [400, 300]
end
version :thumb do
process :resize_to_fill => [64, 64]
end
def extension_whitelist
%w(jpg jpeg gif png)
end
end
They look correct; however, if you actually open thumb within Paint, it's completely blank.
I've tested this with a bunch of different pictures, and most have this happen. But I did notice that if I open the main image, save it (without doing anything), then recreate the versions, it's fixed. Must be something with how it's being saved, or something.
Here is the source image that I've been able to reproduce this issue with.
Thanks.
Very strange behavior. I was very curious about this problem, so I made very simple example on my dev. machine referencing Ryan's Bates
cropping images episode.
You can just follow up, it may help you.
Let's say we generated simple user scaffold, and we have in our DB fields called :name and :avatar of string types.
In our User model we'll mount uploader and create virtual attributes:
class User < ApplicationRecord
mount_uploader :avatar, AvatarUploader
attr_accessor :crop_x, :crop_y, :crop_w, :crop_h
end
Method create in users_controller.rb will look like this (including strong params):
def create
#user = User.new(user_params)
if #user.save
if params[:user][:avatar].present?
render :crop # Render crop template
else
redirect_to #user, notice: "Successfully created user."
end
else
render :new
end
end
# Strong params# Never trust parameters from the scary internet, only allow the white list through.
def user_params
params.require(:user).permit!
end
The image_uploader.rb you posted was good. I will just post mine, as I made large and thumb versions and used resize_to_limit process
instead of resize_to_fit:
version :large do
resize_to_limit(400, 300)
end
version :thumb do
resize_to_fill(64, 64)
end
We can create now crop.html.erb template in views/users folder and populate with code below:
<h1>Crop Avatar</h1>
<%= image_tag #user.avatar_url(:large) %>
<h4>Preview</h4>
<div style="width:100px; height:100px; overflow:hidden">
<%= image_tag #user.avatar.url(:large) %>
</div>
<%= form_for #user do |f| %>
<% %w[x y w h].each do |attribute| %>
<%= f.hidden_field "crop_#{attribute}" %>
<% end %>
<div class="actions">
<%= f.submit "Crop" %>
</div>
<% end %>
When you create new user form it will have avatar attachment. When you upload photo and submit it, it will trigger
def create method and it will check if params are presented, and render the crop.html.erb template:
if params[:user][:avatar].present?
render :crop # Render crop template
else
I haven't included in this example Jcrop library for cropping images, this was very simple example. At the end it should crop 64x64 pixels
by default.
There is also CarrierWave extension to crop uploaded images using Jcrop plugin with preview, which I haven't tried.
I hope it helps
I'm having a problem uploading multiple images via Carrierwave and am not sure if it's a bug or user error (probably the latter). I'm doing everything in a rather standard way though (as per documentation) so it's weird that this doesn't work.
I have the following in my Gemfile:
gem 'carrierwave', github: 'carrierwaveuploader/carrierwave'
my image_uploader.rb:
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
version :thumb do
process :resize_to_limit => [590, 590]
end
version :featured do
process :resize_to_fill => [390, 390]
end
def extension_white_list
%w(jpg jpeg gif png)
end
end
My article.rb file:
class Article < ActiveRecord::Base
mount_uploaders :images, ImageUploader
end
I am letting the params pass from my controller with:
def article_params
params.require(:article).permit(:title, :images, :body)
end
And the _form.html.erb partial uses:
<%= form_for #article, html: { multipart: true } do |f| %>
<%= f.label :images %><br>
<%= f.file_field :images, multiple: true %><br>
<%= f.submit 'Update Article' %>
<% end %>
Oddly, when I upload two images, I am not seeing them passed into the article_params from the update method.
If I pry it, I can see that:
params.require(:article).permit(:images)
Unpermitted parameters: title, images, body
=> {}
Images seems to be unpermitted, even though I explicitly permit it...
Any clue as to what may be incorrect here?
The solution seems to be:
params.require(:article).permit(:title, :body, images: [])
If you take a look in pry on images param, its type is an Array:
> params[:article][:images].class
=> Array
From docs:
To declare that the value in params must be an array of permitted scalar values map the key to an empty array:
params.permit(id: [])
Source: 4.5.1 Permitted Scalar Values
I'm trying to upload images through carrier wave, and using rails.
using minimagick.
Actually, the uploads working properly I think, but images are not shown up.
Also it shows nil value in database.
here's my code.
app/models/user.rb
class User < ActiveRecord::Base
mount_uploader :image, ImageUploader
end
mypage.html.erb (form action to "edit_complete")
<input type="file" name='image'>
users_controller.rb
def edit_complete
user = User.find(session[:user_id])
user.image = params[:image]
user.save
redirect_to :back
end
app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
storage :file
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
end
No errors appeared, but nothing saved in database.
I expect image files should be saved in public/upload folder, and image file should be shown in database in rails c User.all.
However, when I upload 1.png file,
there are nothing saved, and public/upload folder is not generated.
Also in database shows nil value.
Is there any solution for this?
In file upload You need to use multipart option in form tag ie multipart option should be true in form tag.
Try something like this:
<%= form_for #user, :html => {:multipart => true} do |f| %>
<%= f.file_field :image%>
<%= f.submit 'Edit'%>
<% end %>
I am very new to ROR. I have a task to finish:
Here's the Model:
class File::DataImport < ActiveRecord::Base
attr_accessible :created_by, :file_name, :file_source, :updated_at, :updated_by
end
Here's the Controller:
class Files::DataImportsController < ApplicationController
def index
end
def new
end
end
And the views I have are index and new.
I want a field to upload data. The data should be stored in the server and save the filepath into the database in a specified column file_name. The path should be default to all uploading files.
I am stuck with how to start. Please help me to find the solution and I will learn from this.
Thanks in advance.
db/migrate/20110711000004_create_files.rb
class CreateFiles < ActiveRecord::Migration
def change
create_table :files do |t|
t.string :name
# If using MySQL, blobs default to 64k, so we have to give
# an explicit size to extend them
t.binary :data, :limit => 1.megabyte
end
end
end
app/controllers/upload_controller.rb
class UploadController < ApplicationController
def get
#file = File.new
end
end
app/views/upload/get.html.erb
<% form_for(:file,
url: {action: 'save'},
html: {multipart: true}) do |form| %>
Upload your file: <%= form.file_field("uploaded_file") %><br/>
<%= submit_tag("Upload file") %>
<% end %>
app/models/file.rb
class File < ActiveRecord::Base
def uploaded_file=(file_field)
self.name = base_part_of(file_field.original_filename)
self.data = file_field.read
end
def base_part_of(file_name)
File.basename(file_name).gsub(/[^\w._-]/, '')
end
end
app/controllers/upload_controller.rb
def save
#file = File.new(params[:file])
if #file.save
redirect_to(action: 'show', id: #file.id)
else
render(action: :get)
end
end
app/controllers/upload_controller.rb
def file
#file = File.find(params[:id])
send_data(#File.data,
filename: #File.name,
disposition: "inline")
end
app/controllers/upload_controller.rb
def show
#file = File.find(params[:id])
end
app/views/upload/show.html.erb
<h3><%= #file.name %></h3>
<img src="<%= url_for(:action => 'file', :id => #file.id) %>"/>
you should consider using one of the already available solutions like paperclip: https://github.com/thoughtbot/paperclip or carrierwave: https://github.com/jnicklas/carrierwave
Besides the Readmes there are also good tutorials out there:
http://railscasts.com/episodes/134-paperclip
http://railscasts.com/episodes/253-carrierwave-file-uploads
edit: As you want to implement it yourself I recommend examining the sources of the above on Github and try to understand what their code is doing. Also I would not bother implementing it myself, but if you have your reasons this might get you going..
You might want to look into a solution such as carrierwave.
The Github page provides a good explanation on how to use it, but this is also a nice guide.