Last active
December 15, 2015 20:11
-
-
Save ppdeassis/8837098 to your computer and use it in GitHub Desktop.
Rails model template
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ContractLink < ActiveRecord::Base | |
# NOTE: whenever possible, use alphabetic order | |
# includes/extends | |
# -- | |
include MyModule | |
extend MyOtherModule | |
# class definitions, like gem configurations/initializations | |
# -- | |
# example, if using paper_trail gem | |
has_paper_trail | |
# kaminari (pagination) | |
paginates_per 20 | |
# constant definitions | |
# -- | |
CONSTANT_TYPES = [:one, :two, :other] | |
MIN_PROFIT = 30_000 | |
STATUSES = { ready: 1, scheduled: 2, running: 3, success: 4, failure: 5 } | |
# callbacks (order: http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html) | |
# -- | |
after_initialize :defaults, if: :new_record? | |
after_commit :notify | |
# associations, grouped by "kind" (belongs_to, has_one, has_many...) in a "priority" order (belongs, one, many) | |
# -- | |
# NOTE: :some before :that because of alphabetical order | |
belongs_to :some | |
belongs_to :that | |
has_one :thing | |
has_many :tags | |
# attributes section | |
# -- | |
# rails version 3.x | |
attribute_accessible :description, :income, :kind, :name, | |
:status, :that_attributes | |
# enum: rails >= 4.1 (http://edgeapi.rubyonrails.org/classes/ActiveRecord/Enum.html) | |
enum status: STATUSES | |
# nested attrs | |
accepts_nested_attributes_for :that, allow_destroy: true | |
# validations section | |
# -- | |
# NOTE: Order validations by attribute/association name. | |
# | |
# NOTE2: Let's try to use one `validates` per attribute, so we can easily | |
# check what's been validates for each attribute. | |
# | |
# wrong: | |
# validates_uniqueness_of :name | |
# validates_presence_of :name | |
# | |
# right: | |
# validates :name, presence: true, uniqueness: true | |
# | |
validates :income, numericality: { greater_than_or_equal_to: 0 } | |
validates :kind, numericality: { only_integer: true, | |
greater_than_or_equal_to: 0, | |
less_than: CONSTANT_TYPES.size } | |
validates :name, presence: true, uniqueness: true | |
# Association presence is validated through association name (not association_id attribute!) | |
validates :some, presence: true | |
# IMPORTANT: this is not necessary if using `enum` (rails 4.1+) | |
validates :status, in: STATUSES.values | |
# custom validations | |
validate :special_check | |
# associated models with nested attributes | |
validates_associated :that | |
# class methods (like scopes) | |
def self.special | |
where(kind: 'special') | |
end | |
# instance methods | |
def positive? | |
income > MIN_PROFIT | |
end | |
# private stuff (two lines separating it) | |
private | |
# Almost all callback method should be private. | |
# That's true for custom validation methods too. | |
def defaults | |
# this method will run for newly initialized records. | |
# it can be used to set default values. | |
self.status ||= :ready | |
end | |
def notify | |
send_income_changed_message_to(Person.managers) if income_changed? | |
send_something_else_to(Person.project_leaders) | |
end | |
def special_check | |
# note that this error message get's automatically translated to | |
# activerecord.errors.models.contract_link.attributes.that.invalid (if defined) | |
# falling back to default activerecord.errors.invalid ('is not valid'). | |
errors.add(:that, :invalid) unless that.active? | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment