-
Notifications
You must be signed in to change notification settings - Fork 1
Coding Guidelines of the Oregon Digital 2 Project
Oregon Digital 2 is an application that is build using MOSTLY Ruby on Rails. We try to stick to the Ruby on Rails guidelines for development practices found here. https://github.com/rubocop-hq/rails-style-guide
This style guide is maintained by the rubocop community and is utilized by this project via the rubocop gem.
Rubocop is a gem in which helps enforce a style to maintain consistency between multiple programmers. This style is, however, malleable. If there is a style enforcement that makes no sense, or that we don't follow typically, we can deactivate that in the rubocop.yml file. A simple discussion between the programmers is all it takes to move this forward.
In this document, we will try to lay out the "typical style" that is used throughout the project. Ill try to provide code snippets where necessary and keep it as brief as possible.
2 spaces. Not 4. Not 8. Keep it to 2.
def my_method
some_code_stuff
end
Keep as much code as possible in the models. Controllers should be short and concise.
Code can be removed from the model and added as a behavior to the model to keep models organized.
class MyModel
include OregonDigital::MyCoolBehavor
end
Mutations, checks, parsing, etc. can be done in small app services found in app/services. Mostly for encapsulation, testing, and DRY code.
If statements should be no longer than one elsif
if blah
elsif blahblah
else
end
If it is longer than this, use a switch case
case blah
when blah
when ...
...
end
MYGLOBALSTRING = "mystring".freeze This makes them immutable and ensures their value
Helpers are more like a way to sweep code under a rug. Use a service in a view instead of a view helper for more explicit and easy to follow code.
class MyClass
end
module MyModule
end
def my_method
end
If a method needs more than 3, use an options hash or split up functionality more
def my_method(a, b, c)
end
# Or
def my_method(a, opts)
end
Methods should be as short as possible. Single Responsibility Principle
def my_method
return true if blah?
more code
end
Question methods imply truthy value
"mystring#{somevariable}"
not
"mystring" + somevariable
"Hello#{goodbye}" and 'hello'
http://ruby.zigzo.com/2014/08/21/rubys-notation/
# frozen_string_literal: true
# This class is meant to do this thing
class MyClass
end
Always keep an extra empty line at the end of a file. Vim does this automatically by default, so if you use vim you do not need to add an extra empty line.
So how do you tell? Try this one weird trick doctors don't want you to know!
Before you commit, do a quick git diff
or git diff --cached
. Git will
alert you if there's no newline at the end of a file:
diff --git a/foo b/foo
new file mode 100644
index 0000000..1910281
--- /dev/null
+++ b/foo
@@ -0,0 +1 @@
+foo
\ No newline at end of file
Dont indent inside of private and protected method sections
private
def my_private_method
not
private
def my_private_method
{ hello: 'hello' }
{ hello: 'hello' }
not
{ :hello => 'hello' }
Keep them short. Rubocop will yell at you
- S single responsibility principle
- O Open/Close Principle
- L Liskov Substitution Principle
- I Interface Segregation Principle
- D Dependency Inversion Principle
https://thoughtbot.com/blog/back-to-basics-solid
App services, local objects in /lib/oregon_digital
MVC tests. Stuff should be tested. We dont shoot for a specific percentage, but we hover around 90%
To keep track of overrides we add # OVERRIDE of http://github.com/path/to/override/file.rb
above where the override happens. This helps keep track of overrides we have to make. It is also recommended to include a brief description of the override like what is changing and why in addition to the OVERRIDE tag and the path to the base file.
Our development standards are relatively basic
- Atomic commits
- Keep your commits concise
- Squash your own commits using interactive rebase
- Tickets
- Make sure a ticket exists when working on a problem.
- File Bug tickets and use labels when possible
- Descriptive tickets are best tickets (yes I know it doesnt always happen. Try your best)
- PRs
- PRs should address their ticket using
References
orFixes
and the ticket number - PRs should contain QA instructions
- PRs should be atomic. Fix 1 issue.
- Descriptive titles for PRs
- [WIP] in the title of a work in progress PR or use a draft
- PRs dont belong in the project board
- Screenshot when possible to show fix. also use licecap for gif creation to show feature.
- Docker
- docker-compose build
- docker-compose up server
- docker exec -it od2_server_1 bash
- docker system prune
One issue that we have when working with an open source project that is... close to what we want, but not exact, is we have to override many files. It was outlined in the style guide about certain file overrides. With that being said, sometimes overriding a file cant happen. What do we do in this case? We have one of two options
-
We create a class of our own under /lib/oregon_digital/ that inherits from that other class you are trying to update. Then in that class you can override the method that needs to be changed. This is a much more safe and useful approach, especially for testing. Plus, if the class changes, we still have our code there, which should continue working.
-
We override the class directly "like maybe a behavior that is a module" and update it on our side. Modules can be hard to extend and can cause some pain points.
-
We open up the class in an initializer under config/initializers/hacks using #class_eval and append or update their class there. This is quite dangerous and only should happen as a last ditch effort.