Serving files through a controller with carrierwav

2019-07-24 04:47发布

问题:

I'm trying to upload a file of a photo with carrierwave and restrict(for be protected of others who don't be allowed to watch that file and after do this action until the post be published) the file with pundit.

So I create another controller for Attachments:

class AttachmentsController < ApplicationController

  def show
    attachment = Attachment.find(params[:id])
    authorize attachment, :show?
    send_file attachment.file.path, disposition: :inline
  end

end

My AttachmentPolicy:

class AttachmentPolicy < ApplicationPolicy
  class Scope < Scope
    def resolve
      scope
    end
  end

  def show?
    user.try(:admin?) || record.post.has_member?(user)
  end
end

my routes:

resources :attachments, only: [:show]

I create a folder on my_project/uploads, and then config the attachment_uploader.rb:

 def store_dir
    Rails.root.join "uploads/#{model.class.to_s.underscore}/" + \
      "#{mounted_as}/#{model.id}"
  end

create the file config/initializers/carrierwave.rb and put:

CarrierWave.configure do |config|
  config.root = Rails.root
end

So now when I create a new Post with an attachment of a file, don't shows anymore the image. Before it was posible showed by this(in Slim):

 - if @post.attachments.any?
    .attachments
        - @post.attachments.each do |attachment|
          = link_to image_tag(attachment.file.url, class: "img-responsive img-thumbnail"), attachment_path(attachment)

And the new images uploaded don't shows on my post anymore. It's posible just when I click on the link of that image and shows up just for the people are included with restriction protection by pundit, in the path of the AttachmentsController. for example:

http://localhost:3000/attachments/3

And I'm trying to do this scenario spec:

require "rails_helper"

RSpec.feature "Users can view a Post's attached files" do
  let(:user) { create(:user) }
  let(:post) { create(:post, author: user) }
  let!(:attachment) { create(:attachment, post: post, file_to_attach: "spec/fixtures/photo03.jpg") }

  before do
    assign_role!(user, :viewer, post)
    login_as(user)
  end

  scenario "successfully" do
    visit post_path(post)
    find("img[src*='photo03.jpg']").click

    expect(current_path).to eq attachment_path(attachment)
    expect(page).to have_css("img[src*='photo03.jpg']")
  end
end

And complains this error:

$ rspec
...........................................F.............................

Failures:

  1) Users can view a Post's attached files successfully
     Failure/Error: expect(current_path).to eq attachment_path(attachment)

       expected: "/attachments/1"
            got: "/posts/1"

       (compared using ==)

So anyone could help me with this please? I'm trying to do something like the example of the ebook Rails 4 in action, but in this case showing an image.

I try on rails console this:

ap p = Post.last
  Post Load (0.2ms)  SELECT  "posts".* FROM "posts"  ORDER BY "posts"."id" DESC LIMIT 1
#<Post:0x007f9d6c036b08> {
            :id => 4,
         :title => "meus amores",
      :subtitle => "meus amores familia!!",
       :content => "meus amores familia!!",
    :created_at => Wed, 31 May 2017 23:18:56 UTC +00:00,
    :updated_at => Wed, 31 May 2017 23:18:56 UTC +00:00,
     :author_id => 1
}
=> nil

>> at = p.attachments.each do |attachment|
?> attachment.file.url
>> end
=> [#<Attachment id: 4, file: "15036286_1281339961886906_146920697557141175_n.jpg", post_id: 4, created_at: "2017-05-31 23:18:56", updated_at: "2017-05-31 23:18:56">]
>> ap at
[
    [0] #<Attachment:0x007f9d6eadadf0> {
                :id => 4,
              :file => #<AttachmentUploader:0x007f9d6eadaa58 @model=#<Attachment id: 4, file: "15036286_1281339961886906_146920697557141175_n.jpg", post_id: 4, created_at: "2017-05-31 23:18:56", updated_at: "2017-05-31 23:18:56">, @mounted_as=:file, @storage=#<CarrierWave::Storage::File:0x007f9d6eada9b8 @uploader=#<AttachmentUploader:0x007f9d6eadaa58 ...>>, @file=#<CarrierWave::SanitizedFile:0x007f9d6ead97e8 @file="/Users/romenigld/workspace/projects/news_city/uploads/attachment/file/4/15036286_1281339961886906_146920697557141175_n.jpg", @original_filename=nil, @content_type=nil>, @versions={}>,
           :post_id => 4,
        :created_at => Wed, 31 May 2017 23:18:56 UTC +00:00,
        :updated_at => Wed, 31 May 2017 23:18:56 UTC +00:00
    }
]
=> nil
>>

So the file is uploaded in the uploads folder. But not showed anymore!