-
Notifications
You must be signed in to change notification settings - Fork 0
Rails Style Guide
Follow our Ruby Style Guide at all times.
Avoid N+1 queries if at all possible. Use methods like include and joins to prevent this from happening.
Segregate your code into sections. This is best explained with an example:
class TagGroup < ActiveRecord::Base
#################
# RELATIONSHIPS #
#################
belongs_to :image
has_many :tags, through: :tag_group_members
has_many :tag_group_members
###############
# VALIDATIONS #
###############
validates :image, presence: true
validates :tags, presence: true
##############
# ATTRIBUTES #
##############
attr_accessor :tag_group_string
#############
# CALLBACKS #
#############
before_validation :save_tag_group_string
after_initialize :load_tag_group_string
#################
# CLASS METHODS #
#################
##
# This method takes an array of tag names, or a properly
# formatted string, and returns all placements
# which have tags by those names.
def self.by_tag_names(names)
if names.is_a? Array
to_search = names
else
names.split(",").map{|x| x.downcase.strip.squish}
end
self.joins(:tags).where(tags:{name: to_search})
end
####################
# INSTANCE METHODS #
####################
private
def save_tag_group_string
return unless self.tag_group_string && ! self.tag_group_string.empty?
array = self.tag_group_string.split(",")
.map{|str| str.strip.squish.downcase} # Properly format the names
.map{|str| Tag.where(name: str).first_or_create} # Create or find
self.tags = array
end
def load_tag_group_string
return unless self.tags.any?
self.tag_group_string = self.tags.map(&:name).join(", ")
end
endNever use has_and_belongs_to_many, instead using has_many :through.
Prefer RESTful routes.
Use nested routes for models with a very tight relationship. Never nest more than once.
resources :images do
resources :tag_groups
endShallow nesting is also good, although it's not currently in our codebase. This is also true of Concerns. If you can find a use case for them, you should probably use it.
Use member routing where possible.
The string ":controller" should not appear in a routing string. Ever. Same goes for ":action". Both are a security risk.
We use RSpec to write our tests.
Test as much code as you reasonably can. You do not necessarily have to test first, write code later. Sometimes it's best to start getting an outline before you write tests, but it's always good to test as soon as possible.
All models must have a valid factory. You don't need to write the factory validation yourself, since we have one global test that does that. Factories which are intentionally invalid should have names that start with "invalid".
Prefer shoulda matchers to manual testing.
Style Guides
Features
- Frontpage
- About pages
- Help pages
- Uploading Images
- Image pages
- Image comments
- Image search
- Image tagging
- Image collections
- Curating collections
- Creators
- Commissions
- Image of the Day
- Favorites
- User profiles
- User settings
- Error messages
- Reporting
- Admin console
- API
- Notifications
Mockups
Roadmap
Notes