यह "अपलोडिंग विद रेल्स" श्रृंखला का एक और लेख है। आज हम कैरियरवेव से मिलने जा रहे हैं - रेल के लिए सबसे लोकप्रिय फ़ाइल अपलोडिंग समाधानों में से एक। मुझे कैरियरवेव पसंद है क्योंकि इसे शुरू करना आसान है, इसमें बहुत सारी विशेषताएं हैं, और यह समुदाय के सदस्यों द्वारा लिखे गए दर्जनों "कैसे करें" लेख प्रदान करता है, इसलिए आप खो नहीं जाएंगे।
इस लेख में, आप सीखेंगे कि कैसे:
- कैरियरवेव को अपने रेल ऐप में एकीकृत करें
- सत्यापन जोड़ें
- सभी अनुरोधों में फ़ाइलें जारी रखें
- फ़ाइलें हटाएं
- थंबनेल जेनरेट करें
- दूरस्थ स्थानों से फ़ाइलें अपलोड करें
- एकाधिक फ़ाइल अपलोड का परिचय दें
- क्लाउड स्टोरेज के लिए समर्थन जोड़ें
इस लेख का स्रोत कोड GitHub पर उपलब्ध है। पढ़ने का आनंद लें!
नींव रखना
हमेशा की तरह, एक नया रेल एप्लिकेशन बनाकर प्रारंभ करें:
rails new UploadingWithCarrierwave -T
इस डेमो के लिए मैं रेल 5.0.2 का उपयोग करूँगा। कृपया ध्यान दें कि कैरियरवेव 1 केवल रेल 4+ और रूबी 2 का समर्थन करता है। यदि आप अभी भी रेल 3 पर सवारी कर रहे हैं, तो कैरियरवेव संस्करण 0.11 को कनेक्ट करें।
कैरियरवेव को कार्य करते हुए देखने के लिए, हम एक बहुत ही सरल ब्लॉगिंग एप्लिकेशन बनाने जा रहे हैं जिसमें एकमात्र Post
है नमूना। इसमें निम्नलिखित मुख्य विशेषताएं होंगी:
title
(string
)body
(text
)image
(string
)—इस फ़ील्ड में पोस्ट से जुड़ी एक छवि (फ़ाइल का नाम, सटीक होने के लिए) होगी
एक नया माइग्रेशन जनरेट करें और लागू करें:
rails g model Post title:string body:text image:string rails db:migrate
कुछ मार्ग सेट करें:
config/routes.rb
resources :posts root to: 'posts#index'
साथ ही, एक बहुत ही बुनियादी नियंत्रक बनाएं:
posts_controller.rb
class PostsController < ApplicationController before_action :set_post, only: [:show, :edit, :update] def index @posts = Post.order('created_at DESC') end def show end def new @post = Post.new end def create @post = Post.new(post_params) if @post.save redirect_to posts_path else render :new end end def edit end def update if @post.update_attributes(post_params) redirect_to post_path(@post) else render :edit end end private def post_params params.require(:post).permit(:title, :body, :image) end def set_post @post = Post.find(params[:id]) end end
आइए अब सूचकांक . तैयार करते हैं देखें:
views/posts/index.html.erb
<h1>Posts</h1> <%= link_to 'Add post', new_post_path %> <%= render @posts %>
और संबंधित आंशिक:
दृश्य/पोस्ट/_post.html.erb
<h2><%= link_to post.title, post_path(post) %></h2> <p><%= truncate(post.body, length: 150) %></p> <p><%= link_to 'Edit', edit_post_path(post) %></p> <hr>
यहां मैं रेल का उपयोग कर रहा हूं truncate
पोस्ट से केवल पहले 150 प्रतीकों को प्रदर्शित करने की विधि। इससे पहले कि हम अन्य दृश्य और एक फ़ॉर्म आंशिक बनाएं, आइए पहले कैरियरवेव को एप्लिकेशन में एकीकृत करें।
कैरियरवेव को एकीकृत करना
Gemfile . में एक नया रत्न डालें :
जेमफाइल
gem 'carrierwave', '~> 1.0'
भागो:
bundle install
कैरियरवेव अपने कॉन्फ़िगरेशन को अपलोडर . के अंदर संग्रहीत करता है जो आपके मॉडल में शामिल हैं। अपलोडर बनाने के लिए, निम्न कमांड का उपयोग करें:
rails generate uploader Image
अब, ऐप्लिकेशन/अपलोडर . के अंदर , आपको एक नई फ़ाइल मिलेगी जिसका नाम है image_uploader.rb . ध्यान दें कि इसमें कुछ उपयोगी टिप्पणियाँ और उदाहरण हैं, इसलिए आप इसे आरंभ करने के लिए उपयोग कर सकते हैं। इस डेमो में हम ActiveRecord का उपयोग करेंगे, लेकिन कैरियरवेव के पास Mongoid, Sequel और DataMapper के लिए भी समर्थन है।
इसके बाद, हमें शामिल करने या माउंट . करने की आवश्यकता है इस अपलोडर को मॉडल में शामिल करें:
मॉडल/पोस्ट.आरबी
mount_uploader :image, ImageUploader
अपलोडर के पास पहले से ही सामान्य डिफ़ॉल्ट सेटिंग्स हैं, लेकिन कम से कम हमें यह चुनने की जरूरत है कि अपलोड की गई फाइलें कहां संग्रहीत की जाएंगी। अभी के लिए, आइए फ़ाइल संग्रहण का उपयोग करें:
अपलोडर/image_uploader.rb
storage :file
डिफ़ॉल्ट रूप से, फ़ाइलें सार्वजनिक/अपलोड . के अंदर रखी जाएंगी निर्देशिका, इसलिए इसे संस्करण नियंत्रण प्रणाली से बाहर करना सबसे अच्छा है:
.gitignore
public/uploads
आप store_dir
. में भी बदलाव कर सकते हैं किसी अन्य स्थान को चुनने के लिए अपने अपलोडर के अंदर विधि।
इस बिंदु पर, हम फ़ाइलें अपलोड करना शुरू करने के लिए एक नया दृश्य और एक आंशिक प्रपत्र बना सकते हैं:
views/posts/new.html.erb
<h1>Add post</h1> <%= render 'form', post: @post %>
दृश्य/पोस्ट/_form.html.erb
<%= form_for post do |f| %> <div> <%= f.label :title %> <%= f.text_field :title %> </div> <div> <%= f.label :body %> <%= f.text_area :body %> </div> <div> <%= f.label :image %> <%= f.file_field :image %> </div> <%= f.submit %> <% end %>
ध्यान दें कि PostsController
संशोधित करने की आवश्यकता नहीं है क्योंकि हमने पहले ही image
. की अनुमति दे दी है विशेषता।
अंत में, संपादन दृश्य बनाएं:
views/posts/edit.html.erb
<h1>Edit post</h1> <%= render 'form', post: @post %>
इतना ही! आप सर्वर को बूट कर सकते हैं और एक छवि के साथ एक पोस्ट बनाने का प्रयास कर सकते हैं। समस्या यह है कि यह छवि कहीं भी दिखाई नहीं दे रही है, तो चलिए अगले भाग पर चलते हैं और एक शो पेज जोड़ते हैं!
छवियां प्रदर्शित करना
इसलिए, केवल एक ही दृश्य जो हमने अभी तक नहीं बनाया है वह है दिखाएं . इसे अभी जोड़ें:
views/posts/show.html.erb
<%= link_to 'All posts', posts_path %> <h1><%= @post.title %></h1> <%= image_tag(@post.image.url, alt: 'Image') if @post.image? %> <p><%= @post.body %></p> <p><%= link_to 'Edit', edit_post_path(@post) %></p>
जैसा कि आप देख सकते हैं, अनुलग्नक प्रदर्शित करना वास्तव में आसान है:आपको केवल @post.image.url
कहना है किसी छवि के URL को हथियाने के लिए। फ़ाइल का पथ प्राप्त करने के लिए, current_path
. का उपयोग करें तरीका। ध्यान दें कि कैरियरवेव एक image?
भी प्रदान करता है हमारे लिए यह जाँचने की विधि कि क्या कोई अनुलग्नक बिल्कुल मौजूद है (image
विधि स्वयं कभी वापस नहीं आएगी nil
, भले ही फ़ाइल मौजूद न हो)।
अब, किसी पोस्ट पर नेविगेट करने के बाद, आपको एक छवि दिखाई देनी चाहिए, लेकिन यह बहुत बड़ी दिखाई दे सकती है:आखिरकार, हम कहीं भी आयामों को सीमित नहीं कर रहे हैं। बेशक, हम कुछ सीएसएस नियमों के साथ छवि को छोटा कर सकते थे, लेकिन फ़ाइल अपलोड होने के बाद थंबनेल बनाना बेहतर है। हालांकि, इसके लिए कुछ अतिरिक्त चरणों की आवश्यकता है।
थंबनेल बनाना
छवियों को क्रॉप और स्केल करने के लिए, हमें एक अलग टूल की आवश्यकता होती है। बॉक्स के बाहर कैरियरवेव में RMagick और MiniMagick रत्नों के लिए समर्थन है, जो बदले में, ImageMagick की मदद से छवियों में हेरफेर करने के लिए उपयोग किया जाता है। ImageMagick एक ओपन-सोर्स समाधान है जो आपको मौजूदा छवियों को संपादित करने और नए उत्पन्न करने की अनुमति देता है, इसलिए आगे बढ़ने से पहले आपको इसे डाउनलोड और इंस्टॉल करना होगा। इसके बाद, आप दोनों रत्नों में से किसी एक को चुनने के लिए स्वतंत्र हैं। मैं MiniMagick के साथ रहूंगा, क्योंकि इसे स्थापित करना बहुत आसान है और इसका बेहतर समर्थन है:
जेमफाइल
gem 'mini_magick'
भागो:
bundle install
फिर MiniMagick को अपने अपलोडर में शामिल करें:
अपलोडर/image_uploader.rb
include CarrierWave::MiniMagick
अब हमें बस अपने अपलोडर के लिए एक नया संस्करण पेश करना होगा। संस्करणों . की अवधारणा (या शैलियों) का उपयोग कई फ़ाइल अपलोडिंग पुस्तकालयों में किया जाता है; इसका सीधा सा मतलब है कि मूल अनुलग्नक के आधार पर अतिरिक्त फाइलें बनाई जाएंगी, उदाहरण के लिए, विभिन्न आयामों या प्रारूपों के साथ। thumb
. नामक एक नया संस्करण पेश करें :
अपलोडर/image_uploader.rb
version :thumb do process resize_to_fill: [350, 350] end
आपके पास जितने चाहें उतने संस्करण हो सकते हैं और, इसके अलावा, संस्करण अन्य के ऊपर भी बनाए जा सकते हैं:
अपलोडर/image_uploader.rb
version :small_thumb, from_version: :thumb do process resize_to_fill: [20, 20] end
यदि आपने पहले ही कुछ चित्र अपलोड कर दिए हैं, तो उनके पास थंबनेल उपलब्ध नहीं होंगे। हालाँकि, यह कोई समस्या नहीं है, क्योंकि आप उन्हें Rails कंसोल से फिर से बना सकते हैं:
rails c Post.find_each {|post| post.image.recreate_versions!(:thumb) if post.image?}
अंत में, मूल छवि के लिंक के साथ अपना थंबनेल प्रदर्शित करें:
views/posts/show.html.erb
<%= link_to(image_tag(@post.image.thumb.url, alt: 'Image'), @post.image.url, target: '_blank') if @post.image? %>
सर्वर को बूट करें और परिणाम देखें!
सत्यापन जोड़ना
वर्तमान में हमारा अपलोडिंग काम करता है, लेकिन हम उपयोगकर्ता इनपुट को बिल्कुल भी मान्य नहीं कर रहे हैं, जो निश्चित रूप से खराब है। जब तक हम केवल छवियों के साथ काम करना चाहते हैं, आइए .png, .jpg और .gif एक्सटेंशन को श्वेतसूची में रखें:
अपलोडर/image_uploader.rb
def extension_whitelist %w(jpg jpeg gif png) end
आप content_type_whitelist
. को परिभाषित करके सामग्री प्रकार की जांच भी जोड़ सकते हैं विधि:
अपलोडर/image_uploader.rb
def content_type_whitelist /image\// end
वैकल्पिक रूप से, content_type_blacklist
को परिभाषित करके कुछ फ़ाइल प्रकारों, उदाहरण के लिए निष्पादन योग्य, को ब्लैकलिस्ट करना संभव है विधि।
फ़ाइल के प्रकार और एक्सटेंशन की जाँच करने के अलावा, आइए इसे 1 मेगाबाइट से कम होने के लिए लागू करें। ऐसा करने के लिए, हमें ActiveModel के लिए एक अतिरिक्त रत्न समर्थन फ़ाइल सत्यापन की आवश्यकता होगी:
जेमफाइल
gem 'file_validators'
इसे स्थापित करें:
bundle install
अब वांछित सत्यापन प्रस्तुत करें (ध्यान दें कि मैं title
. के लिए चेक भी जोड़ रहा हूं और body
विशेषताएँ):
मॉडल/पोस्ट.आरबी
validates :title, presence: true, length: {minimum: 2} validates :body, presence: true validates :image, file_size: { less_than: 1.megabytes }
कैरियरवेव के त्रुटि संदेशों के लिए I18n अनुवाद जोड़ने के लिए अगली बात यह है:
config/locales/en.yml
en: errors: messages: carrierwave_processing_error: "Cannot resize image." carrierwave_integrity_error: "Not an image." carrierwave_download_error: "Couldn't download image." extension_whitelist_error: "You are not allowed to upload %{extension} files, allowed types: %{allowed_types}" extension_blacklist_error: "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}"
वर्तमान में, हम सत्यापन त्रुटियों को कहीं भी प्रदर्शित नहीं करते हैं, तो चलिए एक साझा आंशिक बनाते हैं:
विचार/साझा/_errors.html.erb
<% if object.errors.any? %> <h3>Some errors were found:</h3> <ul> <% object.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> <% end %>
इस आंशिक को फ़ॉर्म के अंदर नियोजित करें:
दृश्य/पोस्ट/_form.html.erb
<%= render 'shared/errors', object: post %>
अब कुछ अमान्य फ़ाइलें अपलोड करने का प्रयास करें और परिणाम देखें। यह काम करना चाहिए, लेकिन अगर आप एक वैध फ़ाइल चुनते हैं और शीर्षक या बॉडी नहीं भरते हैं, तो चेक अभी भी विफल हो जाएंगे और एक त्रुटि प्रदर्शित होगी। हालाँकि, फ़ाइल फ़ील्ड साफ़ हो जाएगी और उपयोगकर्ता को फिर से छवि चुनने की आवश्यकता होगी, जो बहुत सुविधाजनक नहीं है। इसे ठीक करने के लिए, हमें फ़ॉर्म में एक और फ़ील्ड जोड़ने की आवश्यकता है।
सभी अनुरोधों में फ़ाइलें जारी रखना
फ़ॉर्म रीडिस्प्ले में फ़ाइलों को बनाए रखना वास्तव में काफी आसान है। आपको बस एक नया छिपा हुआ क्षेत्र जोड़ना है और इसे नियंत्रक के अंदर अनुमति देना है:
दृश्य/साझा/_form.html.erb
<%= f.label :image %> <%= f.file_field :image %><br> <%= f.hidden_field :image_cache %>
posts_controller.rb
params.require(:post).permit(:title, :body, :image, :image_cache)
अब image_cache
स्वचालित रूप से पॉप्युलेट हो जाएगा और छवि खो नहीं जाएगी। एक थंबनेल भी प्रदर्शित करना सहायक हो सकता है ताकि उपयोगकर्ता यह समझ सके कि छवि को सफलतापूर्वक संसाधित किया गया था:
दृश्य/साझा/_form.html.erb
<% if post.image? %> <%= image_tag post.image.thumb.url %> <% end %>
छवियां निकालना
रिकॉर्ड संपादित करते समय संलग्न फ़ाइलों को हटाने की क्षमता एक और बहुत ही सामान्य विशेषता है। कैरियरवेव के साथ, इस सुविधा को लागू करना कोई समस्या नहीं है। फ़ॉर्म में एक नया चेकबॉक्स जोड़ें:
दृश्य/साझा/_form.html.erb
<% if post.image? %> <%= image_tag post.image.thumb.url %> <div> <%= label_tag :remove_image do %> Remove image <%= f.check_box :remove_image %> <% end %> </div> <% end %>
और remove_image
. को अनुमति दें विशेषता:
posts_controller.rb
params.require(:post).permit(:title, :body, :image, :remove_image, :image_cache)
इतना ही! किसी इमेज को मैन्युअल रूप से हटाने के लिए, remove_image!
. का इस्तेमाल करें विधि:
@post.remove_image!
दूरस्थ स्थान से अपलोड करना
कैरियरवेव बॉक्स से बाहर एक बहुत अच्छी सुविधा भी प्रदान करता है:दूरस्थ स्थानों से फ़ाइलों को उनके URL द्वारा अपलोड करने की क्षमता। आइए अब एक नया फ़ील्ड जोड़कर और संबंधित विशेषता की अनुमति देकर इस क्षमता का परिचय दें:
दृश्य/साझा/_form.html.erb
<%= f.text_field :remote_image_url %> <small>Enter URL to an image</small>
posts_controller.rb
params.require(:post).permit(:title, :body, :image, :remove_image, :image_cache, :remote_image_url)
वह कितना शांत है? आपको कोई भी परिवर्तन करने की आवश्यकता नहीं है, और आप तुरंत इस सुविधा का परीक्षण कर सकते हैं!
एकाधिक अपलोड के साथ कार्य करना
मान लीजिए हम चाहते हैं कि हमारी पोस्ट में कई अटैचमेंट उपलब्ध हों। वर्तमान सेटअप के साथ यह संभव नहीं है, लेकिन सौभाग्य से, कैरियरवेव ऐसे परिदृश्य का भी समर्थन करता है। इस सुविधा को लागू करने के लिए, आपको या तो एक क्रमबद्ध फ़ील्ड (SQLite के लिए) या एक JSON फ़ील्ड (Postgres या MySQL के लिए) जोड़ने की आवश्यकता है। मुझे बाद वाला विकल्प पसंद है, तो चलिए अब एक नए डेटाबेस एडॉप्टर पर स्विच करते हैं। sqlite3 रत्न को Gemfile . से हटा दें और इसके बजाय पीजी जोड़ें:
जेमफाइल
gem 'pg'
इसे स्थापित करें:
bundle install
डेटाबेस कॉन्फ़िगरेशन को इस तरह संशोधित करें:
config/database.yml
default: &default adapter: postgresql pool: 5 timeout: 5000 development: <<: *default database: upload_carrier_dev username: 'YOUR_USER' password: 'YOUR_PASSWORD' host: localhost
संबंधित पोस्टग्रेज़ डेटाबेस बनाएँ, और फिर माइग्रेशन बनाएँ और लागू करें:
rails g migration add_attachments_to_posts attachments:json rails db:migrate
यदि आप SQLite के साथ रहना पसंद करते हैं, तो कैरियरवेव के दस्तावेज़ीकरण में सूचीबद्ध निर्देशों का पालन करें।
अब अपलोडर को माउंट करें (बहुवचन रूप नोट करें!):
मॉडल/पोस्ट.आरबी
mount_uploaders :attachments, ImageUploader
मैं अटैचमेंट के लिए एक ही अपलोडर का उपयोग कर रहा हूं, लेकिन निश्चित रूप से आप एक अलग कॉन्फ़िगरेशन के साथ एक नया बना सकते हैं।
अपने प्रपत्र में एकाधिक फ़ाइल फ़ील्ड जोड़ें:
दृश्य/साझा/_form.html.erb
<div> <%= f.label :attachments %> <%= f.file_field :attachments, multiple: true %> </div>
जब तक attachments
फ़ील्ड में एक सरणी होने जा रही है, इसे निम्नलिखित तरीके से अनुमति दी जानी चाहिए:
posts_controller.rb
params.require(:post).permit(:title, :body, :image, :remove_image, :image_cache, :remote_image_url, attachments: [])
अंत में, आप पोस्ट के अनुलग्नकों पर पुनरावृति कर सकते हैं और उन्हें हमेशा की तरह प्रदर्शित कर सकते हैं:
views/shared/show.html.erb
<% if @post.attachments? %> <ul> <% @post.attachments.each do |attachment| %> <li><%= link_to(image_tag(attachment.thumb.url, alt: 'Image'), attachment.url, target: '_blank') %></li> <% end %> </ul> <% end %>
ध्यान दें कि प्रत्येक अनुलग्नक में हमारे ImageUploader
. में कॉन्फ़िगर किए गए अनुसार एक थंबनेल होगा . बढ़िया!
क्लाउड स्टोरेज का उपयोग करना
फ़ाइल भंडारण के साथ चिपकना हमेशा सुविधाजनक और/या संभव नहीं होता है, उदाहरण के लिए, हरोकू पर कस्टम फ़ाइलों को संग्रहीत करना संभव नहीं है। इसलिए आप पूछ सकते हैं कि Amazon S3 क्लाउड स्टोरेज के साथ कैरियरवेव से कैसे शादी करें? वैसे यह भी काफी आसान काम है। इस सुविधा को लागू करने के लिए कैरियरवेव फॉग-एज़ रत्न पर निर्भर करता है:
जेमफाइल
gem "fog-aws"
इसे स्थापित करें:
bundle install
आइए कैरियरवेव के लिए एक इनिशियलाइज़र बनाएं और क्लाउड स्टोरेज को विश्व स्तर पर कॉन्फ़िगर करें:
config/initializers/carrierwave.rb
CarrierWave.configure do |config| config.fog_provider = 'fog/aws' config.fog_credentials = { provider: 'AWS', aws_access_key_id: ENV['S3_KEY'], aws_secret_access_key: ENV['S3_SECRET'], region: ENV['S3_REGION'], } config.fog_directory = ENV['S3_BUCKET'] end
कुछ अन्य विकल्प उपलब्ध हैं, जिन्हें दस्तावेज़ीकरण में पाया जा सकता है।
मैं पर्यावरण चर को सुरक्षित तरीके से सेट करने के लिए dotenv-rails रत्न का उपयोग कर रहा हूं, लेकिन आप कोई अन्य विकल्प चुन सकते हैं। हालांकि, सुनिश्चित करें कि आपकी S3 कुंजी जोड़ी सार्वजनिक रूप से उपलब्ध नहीं है, क्योंकि अन्यथा कोई भी आपकी बाल्टी में कुछ भी अपलोड कर सकता है!
इसके बाद, storage :file
. को बदलें लाइन के साथ:
अपलोडर/image_uploader.rb
storage :fog
S3 के अलावा, कैरियरवेव Google संग्रहण और रैकस्पेस पर अपलोड का समर्थन करता है। इन सेवाओं को स्थापित करना भी आसान है।
निष्कर्ष
यह आज के लिए है! हमने कैरियरवेव की सभी प्रमुख विशेषताओं को कवर किया है, और अब आप इसे अपनी परियोजनाओं में उपयोग करना शुरू कर सकते हैं। इसमें कुछ अतिरिक्त विकल्प उपलब्ध हैं, इसलिए दस्तावेज़ीकरण ब्राउज़ करें।
यदि आप फंस गए हैं, तो अपने प्रश्न पोस्ट करने में संकोच न करें। साथ ही, कैरियरवेव के विकी पर एक नज़र डालना उपयोगी हो सकता है, जो कई सामान्य प्रश्नों के उत्तर देने वाले उपयोगी "कैसे करें" लेख होस्ट करता है।
इसलिए मेरे साथ बने रहने के लिए और कोडिंग के लिए मैं आपको धन्यवाद देता हूं!