user2498890
user2498890

Reputation: 1556

Ruby on Rails - how do I remove a post once a date has passed?

I currently have a jobs listing site built with Ruby on Rails, on the add jobs page, one of the inputs is the application date in by/job expiry date field ( <%= job.expirydate %> ). I need to add code which will remove the whole listing from view once that date has passed. At the moment the input field for the expiry dat is just a text input, would this need to be changed and if so how? I'm new to Rails so please forgive my knowledge.

index.html.erb -

<% @jobs.each do |job| %>
        <div class="job">
            <h2><%= link_to job.position, job %></h2>
            <ul class="entry_list">
                <li>Posted on: <%= job.created_at.strftime("#{job.created_at.day.ordinalize} %B %Y") %></li>
                <li>Company: <%= job.company %></li>
                <li>Salary: <%= job.salary %></li>
                <li>Contract Type: <%= job.contract %></li>
                <li>City: <%= job.city %></li>
                <li>Applications in by: <%= job.expirydate %></li>
                <li>Job Type: <%= job.jobtype %></li>
            </ul>
        </div>
    <% end %>

new.html.erb -

<%= simple_form_for @job, html: { multipart: true } do |form| %>
  <h2>Job Position:</h2>
    <%= form.input :position, input_html: { maxlength: 60 }, placeholder: "Job Position", label: false %>
    <%= form.input :company, input_html: { maxlength: 60 }, placeholder: "Company name", label: false %>
    <%= form.input :salary, input_html: { maxlength: 60 }, placeholder: "Salary", label: false %>
    <%= form.input :contract, input_html: { maxlength: 60 }, placeholder: "Contract Type", label: false, collection: ['Full time', 'Part time', 'Internship'], prompt: "Contract Type" %>
    <%= form.input :city, input_html: { maxlength: 60 }, placeholder: "City", label: false %>
    <%= form.input :expirydate, input_html: { maxlength: 60 }, placeholder: "Expiry date", label: false %>
    <%= form.input :jobtype, input_html: { maxlength: 60 }, placeholder: "Job Type", label: false, collection: ['Advertising', 'Art Direction', 'Artworker', 'Copywriting', 'Digital Design', 'Digital Developer', 'Editorial', 'Graphic Design', 'Miscellaneous', 'Motion Design/Animation', 'PR and Marketing', 'Project Management', 'Studio Management'], prompt: "Job Type" %>
    <%= form.input :description, input_html: { maxlength: 60 }, placeholder: "Full job description", label: false %>
    <%= form.input :apply, input_html: { maxlength: 60 }, placeholder: "How to apply", label: false %>
    <h2>Your Contact Details:</h2>
    <%= form.input :contactname, input_html: { maxlength: 60 }, placeholder: "Contact Name", label: false %>
    <%= form.input :contactemail, input_html: { maxlength: 60 }, placeholder: "Contact Email", label: false %>
    <%= form.input :contactphone, input_html: { maxlength: 60 }, placeholder: "Contact Telephone", label: false %>
    <%= form.input :human_sum, label: 'What is 1+1?' %>
    <%= form.button :submit %>
<% end %>

jobs_controller.rb -

class JobsController < ApplicationController

respond_to :html, :js

def index
   @jobs = Job.page(params[:page]).per(20).order(created_at: :desc)
end

def new
   @job = Job.new
end

def show
   @job = Job.find(params[:id])
end

def create
   @job = Job.new(params.require(:job).permit(:human_sum, :position, :company, :salary, :companywebsite, :contract, :city, :expirydate, :jobtype, :description, :apply, :contactname, :contactemail, :contactphone, ))
    if @job.save
      redirect_to root_path
    else
      render "new"
    end
end

end

job.rb -

class Job < ActiveRecord::Base
  validates :position, presence: true
  validates :company, presence: true
  validates :salary, presence: true
  validates :companywebsite, presence: true
  validates :contract, presence: true
  validates :city, presence: true
  validates :expirydate, presence: true
  validates :jobtype, presence: true
  validates :description, presence: true
  validates :apply, presence: true
  validates :contactname, presence: true
  validates :contactemail, presence: true
  validates :contactphone, presence: true

  attr_accessor :human_sum 
  validate :not_a_bot

  private

  def not_a_bot
    if human_sum.to_i != 2 
      errors.add(:human_sum, 'Get out, you bot!') 
    end
  end

  scope :by_contract, -> (contracts) { where(:contract => (contracts|| Job.uniq.pluck(:contract)) ) }
  scope :by_jobtype, -> (jobtypes) { where(:jobtype => (jobtypes|| Job.uniq.pluck(:jobtype)) ) }

end

Upvotes: 0

Views: 1458

Answers (4)

Max Williams
Max Williams

Reputation: 32933

2 things:
1) only list the non-expired jobs

def index
   @jobs = Job.where('expirydate >= ?', Date.today).page(params[:page]).per(20).order(created_at: :desc)
end

2) Enhance your text input for expirydate with an interactive datepicker. The rails built in date pickers aren't very nice as they don't use javascript. There's lots of solutions for this depending on which javascript library you use. For jquery for example see http://jqueryui.com/datepicker/

Upvotes: 0

DGM
DGM

Reputation: 26979

To limit the display to active records, add a scope to the model:

scope :current, -> { expirydate >= Date.current }

and add that to your controller:

@jobs = Job.current.page(params[:page]).per(20).order(created_at: :desc)

Upvotes: 0

Andrew Hendrie
Andrew Hendrie

Reputation: 6415

You can change your index action in your controller to something like this:

Model.find(:all, :conditions => [job.expirydate < Datetime.now])

If you want to delete old records you can create a file for the task:

# lib/tasks/delete_old_records.rake
namespace :delete do
  desc 'Delete records older than 60 days'
  task :old_records => :environment do
    Model.where('created_at > ?', 60.days.ago).each do |model|
      model.destroy
    end

    # or Model.delete_all('created_at > ?', 60.days.ago) if you don't need callbacks
  end
end

Run with:

RAILS_ENV=production rake delete:old_records

Schedule it to run with cron (every day at 8am in this example):

0 8 * * * /bin/bash -l -c 'cd /my/project/releases/current && RAILS_ENV=production rake delete:old_records 2>&1'

You can also use the [whenever][1] gem to create and manage your crontab on deploys:

every 1.day, :at => '8:00 am' do
  rake "delete:old_records"
end

Upvotes: 2

Max Williams
Max Williams

Reputation: 32933

I would make a rake task that deletes all the old posts, and then run it from cron or some other scheduler at regular intervals, eg at 2am every day.

EDIT - although, looking at your question some more, i don't think you actually want to delete them. I think you just want to not show them on the index page. Confusing use of the word "remove" there :)

Upvotes: 0

Related Questions