Rails 6 Auto delete posts from database every 24 hours - ruby-on-rails

is there a way to automatically delete posts/products/articles or anything created on a rails 6 app? I'm trying to build an online image repository that users can upload images that appear only for 24 hours and then get deleted.I have the posting and saving of the pictures/text through active storage and Postgres but i can't get it to get deleted automatically. I've read about whenever sidekiq and resque scheduler but i find it difficult to understand and make it work. i tried from some tutorials and reading the documentation but I'm still having trouble. Can anyone point me in the right direction or try to help me?

You have many options
The simplest one is creating a rake task and setting up a cron job to call this time every minute or something like that. If you call it every 24h you may end up with posts staying for up to 47h.
You can use delayed jobs in two ways
2.1 In an after_create callback, set a job to delete the post after 24 hours. Something like this handle_asynchronously :in_the_future, run_at: Proc.new { 24.hours.from_now }
2.2 Using delayed_job_recurring gem to do the same thing in option one, but without the need of using cron
Edit: I would use option 2.1 since it's the simplest one and easier to maintain, the only downside is that it will create a job for every post, but that shouldn't be a problem even with a million posts a day

Related

How to get a total number of hours in Ruby on Rails app and show it on the index page?

I am working on an app where the user can log his working hours after he finished his shift. The app is developed in Ruby on Rails 4.I used the scaffold method, so it generated the necessary methods for create, read, update, delete. The fields are hours_worked:number overtime:boolean and date:datetime, for now, I plan to expand it later with more functionality, with user login and some other stuf. The model is empty, I did used the rake db:migrate method. Now I know that you can use the count method, as is shown on the official site for active record. I don't have the idea how to get the total number of hours worked and show it on the index page. Consider that I just started learning Rails. Any suggestions?
Sounds like this is best used with the Timers gem.
https://github.com/celluloid/timers
In your Sessions#new method, you'd want to initialize a variable to keep track of the current time. And then every so often, you'd use one of the methods in the gem to update the current time. You could then subtract the difference.
This is hard to answer without any info on how you are actually logging the info, or seeing any of your code. However if you are just looking for general suggestions you could just save start and stop timestamps and compare them. Or ask the user to input time worked. There are probably a thousand different ways to do this. Please be more specific on what exactly you need help with.

Rails: send mail after some time has passed

I have the following scenario:
1. Someone creates a task in Redmine
2. Certain things are done (or not done) with this task
3. In case 3 days have passed since task creation and it is not in the right state, send an email to interested persons.
My question is how do I schedule an email (or the task that will check if an email is required) in exactly three days with Rails? The only option I could think of so far is to create some rake task and run it every couple of minutes. Are there better options?
You've got a couple of options. You probably want to look at Active Job (Rails > 4.2). This lets you schedule a job to run after a specified period:
MyJob.set(wait_until: Time.now + 3.days).perform_later(record)
If you're on a version of rails prior to 4.2 then DelayedJob or Sidekiq or Resque could be used. Active Job is essentially a layer over the top of something like this anyway so a later migration to that shouldn't be too painful.
Alternatively if you don't need to check after exactly 3 days then you could sweep for tasks that need to have emails generated using cron (whenever is a good wrapper for this). You can sweep as often as you want, although every few minutes is probably excessive, and it means you won't have to set up a queueing back end on your server.
It does mean that you'll have to find the tasks that need emails generated for them whereas with the queuing system you'll know exactly which task you're dealing with already. However, it seems like plenty of those tasks won't need an email anyway so it might be more efficient to actively look for the ones that do.
As an alternative you can use https://github.com/resque/resque and https://github.com/zapnap/resque_mailer
Hope this helps.
You can use Whenever to schedule jobs/tasks/method calls ..almost anything
JUST add the gem ...run bundle install..add your code ....update the schedule.rb
for example:
##in schedule.rb
every 5.minutes do
p "============Running rake task Only"
rake "events:notify_user"
end
every 2.hours do
p "============Running rake task and local script as well as calling a method from your code"
command "/usr/bin/some_great_command"
runner "MyModel.some_method"
rake "some:great:rake:task"
end
You can also watch the Railscasts

How do I have an action happen 24 hours after a specific date in Rails?

Im on Rails 4, I'm creating a listing/rental site where people can list things and then other people can rent them. I'm using Stripe to handle all my payments, and I have a form set up that gets the users credit card and makes them a customer when they request to book a rental. After that, the owner of the rental can view the request and confirm or deny it. If they confirm it, the user renting gets their card charged and their money goes into holding.
When a user requests a booking, they choose a pick-up and drop-off date. I would like to have an action that calls a payout from stripe to the listings owner 24 hours after the pick up date. I am not sure how to go about this, so any suggestions are great! Of course if anyone knows of any tutorials implementing such a thing that would be awesome :).
Thanks.
Couple of things you can do
delayed_job: requires a database and a running process to run scheduled jobs; You can use it on heroku as shown here
resque-scheduler: requires redis and resque and a running process to run scheduled jobs. You can use it on heroku as shown here. Use resque-web and resque-cleaner to check and handle failed jobs.
whenever: requires access to cron jobs and your own script to be setup to run every hour or every few minutes to then pickup listings that need to be processed and then process them away. You'll need to work out a good error reporting system. Doesn't run on heroku
heroku scheduler: that is all managed through heroku but essentially gives you the same capabilities as whenever.
Resque would probably be my choice, but you should know better about your domain.
Install the whenever gem and documentation is available here: https://github.com/javan/whenever
Then in config/scheduler.rb file mention your function name and defined in the model or as per requirement. It will be behave like CRON job but major difference is that it can run application internal function as well.
There are many ways of doing this.
All of which involve some sort of data store that is checked every X minutes. Within this data store you can usually set a run on time.
Checkout:
https://github.com/collectiveidea/delayed_job
or
https://github.com/mperham/sidekiq

How can I delete an model entry at a given time (Rails)?

I am trying to create the functionality in my app where a given entry in the database is set to delete at a certain time. I am new to rails an I am unsure how I can achieve this.
For example, once the expired time of an entry has been passed I want it to be deleted automatically. Any hints or ideas how this can be achieved? Thanks again.
You can run a rake task periodically (like every hour or every night). This job will check posts and delete expired ones.
You can schedule rake tasks using whenever gem, for example.
every 3.hours do
rake "jobs:clear_stale"
end
Background job is what will solve your problem. Resque and Sidekiq are two awesome options on background job. You can keep scheduler that runs in specific interval to check if entry has expired and if yes, delete the entry. Here is the railcasts on resque and [this one]. Whenever is also an option but the other two mentioned above are still better.

How to have users create scheduled tasks in rails app deployed on Heroku

I have a rails app deployed on Heroku. I want to add a feature that enables users of the app to set a reminder. I need some way for the app to schedule sending an email at the time specified by the user.
I have found numerous posts referring to using delayed_job for this, but none of the write-ups / tutorials / etc. that I have found directly address what I am trying to accomplish (the descriptions I have found seem more geared towards managing long-running jobs that are to be run "whenever").
Am I on the right track looking at delayed_job for this? If so, can somebody point me towards a tutorial that might help me?
If delayed_job is not quite right for the job, does anybody have a suggestion for how I might approach this?
The most typical way of handling this is to use a cron job. You schedule a job to run every 15 minutes or so and deliver any reminders that come up in that time. Unfortunately, heroku only allows cron jobs to run every hour, which usually isn't often enough.
In this case, I'd use delayedjob and trick it into setting up a recurring task that delivers the notifications as often as necessary. For example, you could create a function that begins by rescheduling itself to run in 10 minutes and then goes on to send any reminders that popped up in the previous 10 minutes.
To view delayedjobs send_at syntax to schedule future jobs check here: https://github.com/tobi/delayed_job/wiki
ADDED after comments:
To send the reminder, you would need to create a function that searches for pending reminders and sends them. For example, let's say you have a model called Reminder (rails 3 syntax cause I like it better):
def self.find_and_send_reminders
reminders = Reminder.where("send_at < ? AND sent = ?", Time.now, false).all
reminders.each do |r|
#the following delayed_job syntax is apparently new, and I haven't tried it. came from the collective_idea fork of delayed_job on github
Notifier.delay.deliver_reminder_email(r)
#I'm not checking to make sure that anything actually sent successfully here, just assuming they did. may want to address this better in your real app
r.update_attributes!(:sent => true)
end
#again using the new syntax, untested. heroku may require the old "send_at" and "send_later" syntax
Reminder.delay(:run_at => 15.minutes.from_now).find_and_send_reminders
end
This syntax assumes you decided to use the single reminder entry for every occurence method. If you decide to use a single entry for all recurring reminders, you could create a field like "last_sent" instead of a boolean for "sent" and use that. Keep in mind these are all just ideas, I haven't actually taken the time to implement anything like this yet so I probably haven't considered all the options/problems.
Check out the runt gem, may be useful for you: http://runt.rubyforge.org/
You can use delayed_job's run_at to schedule at a specific time instead of whenever.
If your application allows the users to change the time of the reminders you need to remember the delayed_job to be able to update it or delete it when required.
Here is more details.
It's good to avoid polling if you can. The worker thread will poll at the database level, you don't want to add polling on top of polling.

Resources