统计特定用户通过Active Storage下载文件的次数。

问题描述 投票:0回答:1

我的两个 岗位 & 评论 模型有 has_one_attached :file. 我想做的是统计特定用户下载帖子文件或评论文件的次数。创建一个类似于 download_counter_cache 在...上 用户 模型,每当该用户下载一个文件时,该模型就会递增。如何实现这个目标?

根据Max的回答进行更新

这是我目前所做的。

# Migration file
class CreateDownloads < ActiveRecord::Migration[6.0]
  def change
    create_table :downloads do |t|
      t.references :user, null: false, foreign_key: true
      t.references :resource, polymorphic: true

      t.timestamps
    end
  end
end
# Routes.rb
 concern :downloadable do
   resources :downloads, only: :create
 end

 resources :posts, concerns: :downloadable do
   [...] # Routes such as like/dislike
   resources :comments, concerns: :downloadable do
     [...] # Routes such as like/dislike
   end
 end
# In posts/_post.html.erb
<%= link_to([@post, :downloads], html_options = {class: 'file w-100'}, method: :post) do %>
  [...]
<% end %>

我的... downloads_controller 和Max的回答中的建议完全一样,我的Post、Comment、User & Download模型也是如此。

问题是,每当我尝试下载时,它都会将我重定向到...。downloads#index 显然是不存在的。我不知道我应该如何创建这个 resource 类,我的两个Post & Comment模型都有has_one_attached :file。

ruby-on-rails ruby rails-activestorage
1个回答
1
投票

max有一个很好的答案,但是如果你只是想在User模型上只有一列来统计所有的下载次数,可以不用多态连接表来完成。

让我们在User模块中添加一个属性来存储计数。

  add_column :users, :download_count, :integer

然后添加一个控制器来处理下载次数并重定向到下载文件。

class DownloadsController < ApplicationController
  def create
    # using find_by so it doesn't throw any errors
    resource = Post.find_by_id(params[:post_id]) || Comment.find_by_id(params[:comment_id])

    if resource
      current_user.increment!(:download_count)
      redirect_to rails_blob_path(resource.file, disposition: "attachment")
    else
      render nothing: true
    end
  end
end

路由会是这样的:

  resources :downloads, only: :create

视图中的下载链接看起来像:

# for post file
<%= link_to 'download file', downloads_path(post_id: @post.id), method: :post %>

# for comment file
<%= link_to 'download file', downloads_path(comment_id: comment.id), method: :post %>

就这么简单。


更新:把方法从new改成post,防止重复渲染。


0
投票

你必须先在用户和commentsposts表或直接在activesupport attachments表之间添加一个连接表。

class Download
  belongs_to :user
  belongs_to :resource, polymorphic: true
end

class Post
  has_many :downloads, as: :resource
end

class Comment
  has_many :downloads, as: :resource
end

class User
  has_many :downloads
end

然后你必须创建一个rails控制器来代理下载,因为下载ActiveSupport附件通常会完全绕过你的Rails应用,直接从存储附件的服务(如S3)下载。

class DownloadsController < ApplicationController
  before_action :authenticate_user! # I'm assuming you're using Devise
  before_action :set_resource

  def create
    @download = @resource.downloads.create!(user: current_user)
    redirect_to @resource.file.service_url
  end

  def set_resource
    if params[:post_id]
      @resource = Post.find(params[:post_id])
    elsif params[:comment_id]
      @resource = Comment.find(params[:comment_id])
    end
  end
end
# routes.rb
concern :downloadable do
  resources :downloads, only: :create
end
resources :posts, concerns: :downloadable
resources :comments, concerns: :downloadable
<%= button_to "Download", [@post, :downloads], method: :post %>

然后,您将通过计算下载表中的行来计算下载量。

© www.soinside.com 2019 - 2024. All rights reserved.