I'm building a self-deleting checklist with Ruby on Rails that is supposed to automatically delete an item once it's expired after 7 days. But the item just remains and goes into the negative ( -1, -2, -3, etc.) I'm not sure where the problem is exactly.
My destroy action is working for everything else.
I've researched all over Stack and Google but I'm not finding anything helpful.
Here is my itemscontroller:
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
And the Item model:
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
If I understood correctly, the problem lies in the destroy
method. It should be
def destroy
if @item.days_left == 0
@item.destroy
end
redirect_to items_path
end
Update:
If you want the items to be self-deleted, you can use whenever gem to a task which does that like below
# 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