Mở đầu
Khi lưu trữ các tệp trong Rails, bộ công cụ đầu tiên mà ta tiếp cận là các gem của bên thứ 3 như: CarrierWave hoặc Paperclip (trước khi không dùng nữa để thay thế cho Active Storage). Active Storage được giới thiệu với Rails 5.2.
Active Storage tạo điều kiện tải tệp lên dịch vụ lưu trữ đám mây như Amazon S3, Google Cloud Storage hoặc Microsoft Azure Storage và đính kèm các tệp đó vào các đối tượng Active Record. Nó đi kèm với một dịch vụ local disk-based để phát triển và thử nghiệm, đồng thời hỗ trợ sao chép tệp tới các dịch vụ cấp dưới để sao lưu và di chuyển.
Sử dụng Active Storage, một ứng dụng có thể chuyển đổi các tệp tải lên hình ảnh với ImageMagick, tạo các bản trình bày hình ảnh của các tệp tải lên không phải hình ảnh như PDF và video cũng như trích xuất siêu dữ liệu từ các tệp tùy ý.
Thực hiện
Vào terminal và tạo một ứng dụng rails mới
rails new app
Tạo ứng dụng, tạo blog app đơn giản với scaffold command.
rails g scaffold Post title:string content:text
Sau khi quá trình hoàn thành, chạy migrate
rails db:migrate
Sau đó vào tùy chỉnh routes
1 2 3 4 5 | <span class="token constant">Rails</span><span class="token punctuation">.</span>application<span class="token punctuation">.</span>routes<span class="token punctuation">.</span>draw <span class="token keyword">do</span> resources <span class="token symbol">:posts</span> root to<span class="token punctuation">:</span> <span class="token string">'posts#index'</span> <span class="token keyword">end</span> |
Bây giờ ta sẽ thêm ảnh vào bài đăng của mình.
Đầu tiên ta cần cài đặt active storage vào bài đăng của mình.
rails active_storage:install
Sau khi chạy lệnh này, Rails sẽ tạo một file migration cho bạn. Khi kiểm tra sẽ thấy tạo 2 bảng khác nhau: active_storage_blobs và active_storage_attachments.
Sau đó ta chạy file migrate
rails db:migrate
Tiếp theo ta thêm vào model như sau:
1 2 3 4 | <span class="token keyword">class</span> <span class="token class-name">Post</span> <span class="token operator"><</span> <span class="token constant">ApplicationRecord</span> has_one_attached <span class="token symbol">:image</span> <span class="token keyword">end</span> |
Một lần nữa, chúng ta sẽ cần thêm image vào controller của mình ở cuối method post_params, thêm image vào các thuộc tính của modle.
1 2 3 4 | <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">post_params</span></span> params<span class="token punctuation">.</span><span class="token keyword">require</span><span class="token punctuation">(</span><span class="token symbol">:post</span><span class="token punctuation">)</span><span class="token punctuation">.</span>permit<span class="token punctuation">(</span><span class="token symbol">:title</span><span class="token punctuation">,</span> <span class="token symbol">:content</span><span class="token punctuation">,</span> <span class="token symbol">:image</span><span class="token punctuation">)</span> <span class="token keyword">end</span> |
Trong app/view/posts/_form.html.erb, chúng ta sẽ chỉnh sửa tệp bằng cách thêm input thêm image.
1 2 3 4 5 | <span class="token operator"><</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"field"</span><span class="token operator">></span> <span class="token operator"><</span><span class="token string">%= form.label :image %> <%=</span> form<span class="token punctuation">.</span>file_field <span class="token symbol">:image</span> <span class="token string">%> </div></span> |
Bây giờ chúng ta cần tải hình ảnh trong index và show
1 2 3 4 5 6 | <span class="token comment">#app/views/posts/index.html.erb</span> <span class="token operator"><</span><span class="token operator">%</span> <span class="token keyword">if</span> post<span class="token punctuation">.</span>image<span class="token punctuation">.</span>attached<span class="token operator">?</span> <span class="token string">%> <td></span><span class="token operator"><</span><span class="token operator">%</span><span class="token operator">=</span> image_tag post<span class="token punctuation">.</span>image <span class="token string">%></td></span> <span class="token operator"><</span><span class="token operator">%</span> <span class="token keyword">end</span> <span class="token operator">%</span><span class="token operator">></span> |
1 2 3 4 5 6 7 8 | <span class="token comment">#app/views/posts/show.html.erb</span> <span class="token operator"><</span>p<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">%</span> <span class="token keyword">if</span> <span class="token variable">@post</span><span class="token punctuation">.</span>image<span class="token punctuation">.</span>attached<span class="token operator">?</span> <span class="token string">%> <%= image_tag @post.image %></span> <span class="token operator"><</span><span class="token operator">%</span> <span class="token keyword">end</span> <span class="token string">%> </p></span> |
Bây giờ ta hoàn toàn có thể đăng ảnh kèm trong bài post, tuy nhiên bây giờ chúng ta muốn khi đăng bài post bắt buộc phải có ảnh kèm theo, ta sử dụng gem active_storage_validations. Ta thêm gem “active_storage_validations” vào trong gem file và bundle install.
Sau đó :
1 2 3 4 | <span class="token comment"># app/models/post.rb</span> validates <span class="token symbol">:image</span><span class="token punctuation">,</span> attached<span class="token punctuation">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> content_type<span class="token punctuation">:</span> <span class="token string">%i[png jpg jpeg]</span> |
Với validation trên ta chỉ chấp nhận những ảnh có đuôi png, jpg và jpeg kèm theo đó khi tạo post cần phải có ảnh đính kèm khi tạo post.
Như vậy là ta có thể đăng post có kèm theo file ảnh.
Nguồn tham khảo:
https://hackernoon.com/uploading-files-into-ruby-on-rails-activestorage-gv1r3ukr