Read the following chapters from The Pragmatic Programmer, anniversary edition (in our library):
Read the following chapters from Clean Code (in our library):
Also read:
Read the following chapters from our book Growing Rails Application in Practice:
Discuss with your mentor what you took away from each topic.
Apart from the concepts mentioned above, there are a many more rules that are good to follow most of the time. For example:
We're building an e-commerce app where users can create and view invoices.
This is our current model:
class Invoice < ApplicationRecord
has_many :items
validates_presence_of :recipient_address, :number
end
class Invoice::Item < ApplicationRecord
belongs_to :invoice
belongs_to :product
validates_numericality_of :units
end
class Product < ApplicationRecord
validates_presence_of :description
validates_numericality_of :unit_price
end
This is a view that shows an invoice:
%h1
Invoice
= @invoice.number
%h2 Recipient
= @invoice.recipient_address
%h2 Items
%table
%tr
%th Description
%th Quantity
%th Item total
- @invoice.items.each do |item|
%td= item.product.description
%td= item.units
%td= item.units * item.product.unit_price
%tr
%th
Invoice total
%td(colspan=3)
= @invoice.items.sum { |item| item.units * item.product.unit_price } * 1.19
How would you judge the quality of this code?
Try to apply what you learned with a refactoring of the model and the view. What are the advantages of your solution?
Let's say there is the a MovieSearch
class in your project with the following public API:
class MovieSearch
def initialize(query)
@query = query
end
def results
Movie.where('title LIKE ?', @query)
end
end
search = MovieSearch.new('Interstellar')
search.results.each do |movie|
puts movie.title
end
Now the current user should not be allowed to search all movies, but only a subset based on their role and the movie's state. A naive inline authorization could look like this:
class MovieSearch
def initialize(query, current_user)
@query = query
@current_user = current_user
end
def results
scope = Movie.where('title LIKE ?', @query)
unless current_user.moderator?
scope = scope.where('state = "approved" OR user_id = ?', @current_user.id)
end
scope
end
end
Try to come up with an alternative implementation where the two concepts (movie search and authorization) are less coupled.