我的两个 岗位 & 评论 模型有 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。
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,防止重复渲染。
你必须先在用户和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 %>
然后,您将通过计算下载表中的行来计算下载量。