自删除清单不删除项目

Self deleting checklist not deleting items

我正在 Rails 上使用 Ruby 构建一个自删除清单,该清单应该会在项目 7 天后过期后自动删除。 但是该项目只是保留下来并变为负数(-1、-2、-3 等) 我不确定问题到底出在哪里。

我的销毁操作对其他一切都有效。

我研究了整个 Stack 和 Google,但没有发现任何有用的东西。

这是我的物品控制器:

class ItemsController < ApplicationController
  before_action :find_item, only: [:show, :edit, :update, :destroy]

  def index
    @items = Item.all
    @items = Item.where(user: current_user)
  end

  def new
    @item = Item.new
    # authorize @item
  end

  def create
    @item = current_user.items.build(item_params)
    @item.expires_at = Time.now + 7.days
    # authorize @item
     if @item.save
      redirect_to @item, notice: "Item was added!"
     else
       flash[:error] = "Error adding item. Please try again! Your organization depends on it!"
       render :new
     end
  end

  def show
    @item = Item.find(params[:id])
    @item.days_left 
  end


  def edit
    @item = Item.find(params[:id])
  end

  def update
    @item = Item.find(params[:id])
    if @item.update_attributes(item_params)
      flash[:notice] = "Item was updated."
       redirect_to item_path
    else
       flash[:error] = "There was an error saving the item. Please try again."
       render 'edit'
    end
  end

  def destroy
    if @item.days_left == 0
      @item.destroy
    end

    @item.destroy
    redirect_to items_path
  end



  def completed
    @item = Item.find(params[:id])
    @item.update_attribute(:completed, true)
    redirect_to items_path
  end

  private


  def item_params
    params.require(:item).permit(:name, :user, :description)
  end

  def find_item
    @item = Item.find(params[:id])
  end
end

物品型号:

    class Item < ActiveRecord::Base
  belongs_to :user

  def completed
     completed == true
  end

   default_scope { order('expires_at ASC') }

   def days_left
      7 - (DateTime.now.to_date - created_at.to_date).to_i
   end

end

Routes.rb

Rails.application.routes.draw do


  get 'about' => 'welcome#about'

  get "users/dashboard" => "items#index"

  root to: 'welcome#index'



  devise_for :users
  resources :users, only: [:update, :show, :index]
  resources :items do
    member do
      patch :completed
    end
  end
end

Schema.rb

ActiveRecord::Schema.define(version: 20150823054939) do

  create_table "items", force: :cascade do |t|
    t.string   "name"
    t.integer  "user_id"
    t.datetime "created_at",  null: false
    t.datetime "updated_at",  null: false
    t.boolean  "completed"
    t.datetime "expires_at"
    t.text     "description"
  end

  add_index "items", ["user_id"], name: "index_items_on_user_id"

  create_table "users", force: :cascade do |t|
    t.string   "email",                  default: "", null: false
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.string   "name"
    t.integer  "sign_in_count",          default: 0,  null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
    t.string   "confirmation_token"
    t.datetime "confirmed_at"
    t.datetime "confirmation_sent_at"
    t.string   "unconfirmed_email"
    t.datetime "created_at",                          null: false
    t.datetime "updated_at",                          null: false
    t.string   "role"
  end

  add_index "users", ["email"], name: "index_users_on_email", unique: true
  add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true

end

如果我没理解错的话,问题出在destroy方法上。应该是

def destroy
  if @item.days_left == 0
  @item.destroy
  end
  redirect_to items_path
end

更新:

如果您想要自行删除项目,您可以使用 whenever gem 执行如下所示的任务

# lib/tasks/delete_expired_items.rake
every :hour do 
  runner "Item.delete_expired_items"
end

#item.rb
def delete_expired_items
  #this will delete the items that are created 7 days ago from today.
  self.where('created_at =?', 7.days.ago).destroy_all
end

您需要创建一个任务来验证过期项目并自动删除它们。看看https://github.com/collectiveidea/delayed_job.

在您的代码中,仅当用户想要销毁项目时才会调用销毁操作。