-
-
Save madwork/7356782 to your computer and use it in GitHub Desktop.
| class Attachment < ActiveRecord::Base | |
| mount_uploader :attachment, AttachmentUploader | |
| # Associations | |
| belongs_to :attached_item, polymorphic: true | |
| # Validations | |
| validates_presence_of :attachment | |
| validates_integrity_of :attachment | |
| # Callbacks | |
| before_save :update_attachment_attributes | |
| # Delegate | |
| delegate :url, :size, :path, to: :attachment | |
| # Virtual attributes | |
| alias_attribute :filename, :original_filename | |
| private | |
| def update_attachment_attributes | |
| if attachment.present? && attachment_changed? | |
| self.original_filename = attachment.file.original_filename | |
| self.content_type = attachment.file.content_type | |
| end | |
| end | |
| end |
| # encoding: utf-8 | |
| require 'carrierwave/processing/mime_types' | |
| class AttachmentUploader < CarrierWave::Uploader::Base | |
| include CarrierWave::MimeTypes | |
| storage :file | |
| def store_dir | |
| "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" | |
| end | |
| process :set_content_type | |
| end |
| class AttachmentsController < ApplicationController | |
| before_action :find_attachable | |
| def create | |
| @attachable.attachments.create attachment_params | |
| redirect_to @attachable | |
| end | |
| private | |
| def attachment_params | |
| params.require(:attachment).permit(:attachment) | |
| end | |
| # could be improve and include into concerns | |
| # http://api.rubyonrails.org/classes/ActiveSupport/Concern.html | |
| def find_attachable | |
| params.each do |name, value| | |
| return @attachable = $1.classify.constantize.find(value) if name =~ /(.+)_id$/ | |
| end | |
| end | |
| end |
| # Required gem ryanb/nested_form | |
| # https://github.com/ryanb/nested_form | |
| <%= nested_form_for @post, html: { multipart: true } do |f| %> | |
| <p><%= f.link_to_add "Add an attachment", :attachments %></p> | |
| <%= f.fields_for :attachments do |attachment_form| %> | |
| <%= attachment_form.file_field :attachment %> | |
| <%= attachment_form.hidden_field :attachment_cache %> | |
| <%= attachment_form.link_to_remove "Remove this attachment" %> | |
| <% end %> | |
| <% end %> |
| class Post < ActiveRecord::Base | |
| has_many :attachments, as: :attached_item, dependent: :destroy | |
| # http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html#method-i-accepts_nested_attributes_for | |
| accepts_nested_attributes_for :attachments, allow_destroy: true, reject_if: proc { |attributes| attributes[:attachment].nil? } | |
| end |
| class PostsController < ApplicationController | |
| def new | |
| @post = Post.new | |
| end | |
| def create | |
| @post = Post.create post_params | |
| redirect_to @post | |
| end | |
| private | |
| def post_params | |
| params.require(:post).permit(attachments_attributes: [:id, :attachment, :attachment_cache, :_destroy]) | |
| end | |
| end |
| App::Application.routes.draw do | |
| # Concerns must be declared before | |
| # http://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Concerns.html | |
| concern :attachable do | |
| resources :attachments, only: :create | |
| end | |
| resources :posts, concerns: [:attachable] | |
| end |
| create_table "attachments", force: true do |t| | |
| t.integer "attached_item_id" | |
| t.string "attached_item_type" | |
| t.string "attachment", null: false | |
| t.string "original_filename" | |
| t.string "content_type" | |
| t.datetime "created_at" | |
| t.datetime "updated_at" | |
| end | |
| add_index "attachments", ["attached_item_type", "attached_item_id"] |
Flawless. Thank you.
I am getting error if try to destroy image "undefined method `name' for nil:NilClass"
Thank you for sharing this.
In my case I did not use nested form. I used the standard form_for and fields_for helpers.
<%= form_for @organization, url: {action: "create"} do |f| %> <%= f.text_field :name %> <%= f.fields_for :image do |image_form| %> <%= image_form.file_field :image %> <%= image_form.hidden_field :image_cache %> <% end %> <%= f.submit "Create" %> <% end %>
For this to send the request with the expected 'image_attributes' parameters and not just a nested 'image' parameter, you need the parent object instance to initialize the nested object.
This means that in the controller or view, you will need to do something like this @organization.build_image
God Bless.
Does this code apply to Rails 5. I have tried this code but nothing gets stored in the database.
Works for me. My only challenge is I added a "Description" and "Order" to my attachments table. I'm trying to figure out how to 'edit' those fields with an edit view/update model without actually uploading a new image. (works if you update the image too)
Form redisplay in case of validation errors doesn't work. I have has_one association.
What should i need to do for that.
Thanks