Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
ruby-on-rails-exploration-part-2

Introduction

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:

  • Custom Validation
  • Pagination

Custom Validation

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

Pagination

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

Conclusion

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!

Gist

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.