我正在开发一个Web应用程序,用户可以在其中创建和管理他们的慢跑会话(Jogs).管理员用户应该能够删除任何慢跑,而普通用户应该只能删除他们自己的慢跑.此外,经理应该能够删除自己的JOG,但不能删除其他用户的JOG.我已经在控制器的销毁操作中设置了适当的条件来处理这些权限.然而,尽管实现了这些条件,我仍然面临着删除功能的问题:

作为管理员,我可以删除我自己的Jog,但我无法删除其他用户创建的Jog,链接会显示出来,但当我点击它时,我会返回到我的rooturl,什么都不会发生,也不会出现任何错误.

class JogsController < ApplicationController
    before_action :logged_in_user, only: [:create, :destroy]
    before_action :correct_user, only: :destroy
    before_action :set_jog, only: [:show, :edit, :update, :destroy]
    before_action :authorize_jog_deletion, only: :destroy

    def weekly_report
      @jog = Jog.find(params[:id])
      @selected_week = params[:week].to_i if params[:week].present?
    结束


    def create
    @jog = current_user.jogs.build(jog_params)
    if @jog.save
    flash[:success] = "Jog session created!"
    redirect_to root_url
    else
        @feed_items = current_user.feed.paginate(page: params[:page])
        r结束er 'static_pages/home'        
    结束
    结束
  
    def destroy
      authorize_jog_deletion
      @jog.destroy
     flash[:success] = "Jog deleted"
     redirect_to request.referrer || root_url
    结束

    

   
    
    私有

    def jog_params
        params.require(:jog).permit(:distance_km, :duration_minutes, :date)
    结束  

    def correct_user
        @jog = current_user.jogs.find_by(id: params[:id])
        redirect_to root_url if @jog.nil?
      结束
      
      def set_jog
        @jog = Jog.find(params[:id])
      结束

      def authorize_jog_deletion
        unless current_user.admin? ||
               (@jog.user == current_user) ||
               (current_user.manager? && current_user == @jog.user)
          flash[:danger] = "You are not authorized to delete this jog"
          redirect_to (root_url)
        结束
      结束
     
结束
  

App/view/jogs/_jog.html.erb

<div class="weekly-report-button-container">
<%= link_to "View Weekly Report", weekly_report_jog_path(jog), class: "btn btn-primary" %>
</div class="weekly-report-button-container">
<li id="jog-<%= jog.id %>">

  <%= link_to gravatar_for(jog.user, size: 50), jog.user %>
  <span class="user"><%= link_to jog.user.name, jog.user %></span>
  <span class="content">
    Distance: <%= jog.distance_km %> km |
    Duration: <%= jog.duration_minutes %> minutes |
    Date: <%= jog.date.strftime('%Y-%m-%d') %>
  </span>
  <span class="average-speed">Average Speed: <%= jog.average_speed %> km/h</span>
  <span class="timestamp">
    Jogged on the site <%= time_ago_in_words(jog.date) %> ago.
    
    <% if current_user.admin? || (current_user.manager? && jog.user_id == current_user.id) || (jog.user_id == current_user.id) %>
    <%= button_to "delete", jog_path(jog), method: :delete, data: { confirm: "Are you sure you want to delete this jog?" } %>
  <% 结束 %>
  
  </span>
</li>

app/models/jog.rb

类应用程序记录(&L) 归属者:用户

验证:user_id,Presence:True 验证:日期,存在:真,包含:{in:(Date.new(2020)..Date.Today)} 验证:距离_公里,存在:真,数值:{大于:0} 验证:持续时间_分钟,状态:真

Def admin? 行政部 结束

Def经理? 经理 结束

Def self.Callate_Week_Total_Discipline(用户) Week_Total=}

user.jogs.each do |jog|
  week = jog.date.cweek
  weekly_total_distance[week] ||= 0
  weekly_total_distance[week] += jog.distance_km
结束

weekly_total_distance

结束

定义平均速度 如果持续时间_分钟为零,则返回0?

(distance_km / duration_hours).round(2)

结束

私有

def duration_hours duration_minutes / 60.0 结束 结束

config/routes.rb
Rails.application.routes.draw do
    root 'static_pages#home'
    get 'help' => 'static_pages#help'
    get 'about' => 'static_pages#about'
    get 'contact' => 'static_pages#contact'
    get 'signup' => 'users#new'
    get 'login' => 'sessions#new'
    post 'login' => 'sessions#create'
    delete 'logout' => 'sessions#destroy'
  resources :users do
    member do
      get :following, :followers
    结束
  结束
  resources :users
  resources :account_activations, only: [:edit]
  resources :password_resets, only: [:new, :create, :edit, :update]
  resources :jogs, only: [:create, :destroy]
  resources :relationships, only: [:create, :destroy]
  resources :jogs do
    member do
      get :weekly_report
    结束
  结束
  
结束


我还try 将删除链接切换到一个按钮,并且我已经确认在控制器的销毁操作中正确设置了条件.尽管做出了所有这些努力,我仍然面临着这些问题.此外,其他删除链接在我的应用程序中也可以使用,但这个不能.

推荐答案

如果CURRENT_USER是ADMIN,则correct_user设置@jog是意外的,并且始终使用current_user,这不是您想要的:

class JogsController < ApplicationController
  before_action :logged_in_user, only: [:create, :destroy]
  before_action :set_jog, only: [:show, :edit, :update, :destroy, :weekly_report]
  before_action :authorize_jog_deletion, only: :destroy
  # before_action :correct_user, only: :destroy

  def weekly_report
    # @jog = Jog.find(params[:id])
    @selected_week = params[:week].to_i if params[:week].present?
  end

  def create
    @jog = correct_user.jogs.new(jog_params)
    if @jog.save
      flash[:success] = "Jog session created!"
      redirect_to root_url
    else
      @feed_items = correct_user.feed.paginate(page: params[:page])
      render "static_pages/home"
    end
  end

  def destroy
    # authorize_jog_deletion
    @jog.destroy
    flash[:success] = "Jog deleted"
    # redirect_to request.referrer || root_url
    redirect_back_or_to root_path
  end

  private

  # as admin you want to manage other people's stuff so you need to act on
  # their behalf
  # https://github.com/ankane/pretender
  def correct_user
    @correct_user ||= if current_user.admin?
      # figure out a way to set the user, it cannot be current_user, because
      # that's you, and you need the other guy
      @jog&.user || User.find(params[:user_id])
    else
      current_user
    end
  end

  # don't reinvent it
  # https://github.com/CanCanCommunity/cancancan
  # https://github.com/varvet/pundit
  def authorize_jog_deletion
    unless current_user.admin? || (@jog.user == current_user)
      # seems redundant. this covers it ^
      # || (current_user.manager? && current_user == @jog.user)

      flash[:danger] = "You are not authorized to delete this jog"
      redirect_to(root_url)
    end
  end

  def set_jog
    @jog = Jog.find(params[:id])
  end

  def jog_params
    params.require(:jog).permit(:distance_km, :duration_minutes, :date)
  end
end

Ruby-on-rails相关问答推荐

仅当未在带有ENV[';Dyno';]的Heroku问题上运行时才初始化Sidekiq Cron

参数数量错误(给定1个,预期为0个;必需关键字:IO、文件名)-活动存储

Rails版本7.1.2:当验证失败且控制器发送422状态时,JS停止工作

仅在两个子域间共享Rails cookies,并为所有其他子域使用单独的cookie

Rails 6:强类型原始 SQL 查询返回数组类型

Ruby Hash 中 tap / delete 和 except 的区别

多行与内联块之间的不同行为

在 Datatable Ajax 调用中通过 Ajax 更新 div

Rails 路由到唯一索引

Factory Girl + Mongoid 在fixture 中嵌入文档

Rails:如何小写非英文字符串?

耙路由错误缺少:路由定义上的操作键

如何避免 RSpec 3.0 中 stub_chain 的弃用警告?

添加自定义字段/列以使用 Rails 4 进行设计

在 ruby​​ 中构建公钥时,是什么导致既不是 PUB key 也不是 PRIV key::nested asn1 错误?

如何在 Rails 中设置路由的默认格式?

用于在多行上链接调用的 Ruby 约定

在任何来源中都找不到 thread_safe-0.3.0

sass-rails 助手image-url、asset-url在 rails 3.2.1 中不起作用

无论何时 gem 在 Heroku 上运行 cron 作业(job)