Patrique Ouimet
Senior Backend Software Engineer
Dec 5, 2018
Part 2! This is an overview of things I've learnt while working on my side project Anon Forum in Ruby on Rails.
Today's topics:
There's a few ways to setup custom validation most of which is documented here Performing Custom Validations. The documentation is complete but a little difficult for me to digest so here's how I did it:
app/validators/bad_word_validator.rb
class BadWordValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 90.minutes)
bad_words = cache.fetch('bad_words') do
File.readlines('repos/List-of-Dirty-Naughty-Obscene-and-Otherwise-Bad-Words/en').map { |a| a.strip }
end
value_array = ActionController::Base.helpers.strip_tags(value.to_s).gsub(/[^0-9a-z ]/i, '').split
if value_array.length > 0
for word in value_array
if bad_words.include? word.downcase
record.errors[attribute] << (options[:message] || "The #{attribute} must not contain bad words.")
break
end
end
end
end
end
After the validation class is setup you just need to add bad_word: true as a validation requirement on the model attribute
app/models/post.rb
class Post < ApplicationRecord
validates :title, presence: true, bad_word: true
validates :body, presence: true, bad_word: true
*
*
*
end
Adding pagination is actually quite simple, first add the following gem to your Gemfile:
gem 'will_paginate', '~> 3.1.0'
Run bundle install, then add the following to any queries (this is a sample from my projects post controller index method)
def index
page = params[:page].present? ? params[:page] : 1
@posts = params[:q].present? ?
Post.where('title LIKE ?', "%#{params[:q]}%").paginate(:page => page) :
Post.paginate(:page => page)
end
Now in the view add this:
<%= will_paginate @posts %>
That's it! It'll display the pagination if needed, it'll show up as links labeled: Previous, 1...n, Next
That's it for this post! Figuring out the custom validation took me longer than it should have (likely due to how new I am to ruby/rails) but once I figured it out it all made sense. The pagination was incredibly easy to implement but I'm a little surprised it required a gem be added. If you'd like to see the progress and commits take a look here: Anon Forum.
Feel free to share! Thanks!