Reputation: 919
For learning purposes I created a blog, now I want to destroy a post automatically after 30 days from its creation. how can I do it?
This is my Posts controller
def index
@posts = Post.all
end
def create
@post = current_user.posts.new(post_params)
@post.save
redirect_to posts_path
end
def destroy
@post.destroy
redirect_to posts_path
end
Upvotes: 1
Views: 1871
Reputation: 5598
Along with the aforementioned whenever
gem, you can also use two gems called Sidekiq and Sidetiq for scheduling tasks/workers.
I've been using these on a large app at work and am very pleased with it. It's fast (uses Redis, added with a simple gem, reliable, and easy to use).
# in app/workers/clean_posts.rb
class CleanPosts
include Sidekiq::Worker
include Sidetiq::Schedulable
recurrence { monthly }
def perform
# stealing from toolz
Post.where('created_at >= :thirty_days_ago', thiryty_days_ago: Time.now - 30.days).destroy_all
end
end
This will, however, remove the posts from your DB and they will no longer be accessible by your application.
Upvotes: 3
Reputation: 3079
To achieve desired result, you need to change your index
action like this:
def index
@posts = Post.where(created_at: 30.days.ago..Time.now)
end
In such way, you won't need to destroy posts and you will get the desired result.
If you need to limit access to the older posts, then you can use:
def show
@post = Post.where(created_at: 30.days.ago..Time.now).find(params[:id])
end
And, if we are speaking about code beauty, then you should move where(created_at: 30.days.ago..Time.now)
part to a scope in your model, like this:
class Post
...
scope :recent, -> { where(created_at: 30.days.ago..Time.now) }
end
And use it like this:
Post.recent #=> to get list of recent posts
Post.recent.find(params[:id]) #=> to get recent post with specified id
Upvotes: 1
Reputation: 641
I would set up a task with whenever that runs every 1 day.
To generate a task:
rails g task posts delete_30_days_old
Then on the created file (lib/tasks/posts.rb), add the following code:
namespace :posts do
desc "TODO"
task delete_30_days_old: :environment do
Post.where(['created_at < ?', 30.days.ago]).destroy_all
end
end
This is of course if you want to delete the posts that have more than 30 days, other answers might as well work but I would rather have my database with clean data that I'll use on my application.
Upvotes: 6
Reputation: 8295
You can not do that from your controller, you need to add some functionality to your application.
You will need a cron job running everyday that will look for posts that are more than 30 days old and destroy them.
eg Post.where('created_at < ?', 30.days.ago)
For handling the cron jobs better you might consider using the whenever gem that helps a lot and keeps the cron setup in your app.
Upvotes: 0
Reputation: 891
Posts will be stored in your database. The model is what interacts with your database. Your controller never sees the database, it only sees what the model shows it. If you wanted to pull from the database using your model inside the controller you could do it with this code.
@posts = Post.where('created_at >= :thirty_days_ago', thiryty_days_ago: Time.now - 30.days)
Post
in this code calls you app/model/Post.rb which inherited active record. .where
is the active record method that looks at your database based on the stuff you define. Here we have defined to pull only rows where the created_at
column has a time in it that is 30 days ago.
If you look inside your database you'll notice the created_at column was automagically put in there for you.
Upvotes: 3