Remember our new/edit Food form?
Right now we can pretty much input anything in this form and it will process it anyway.
But we actually don't want, for instance, our "price" field is filled with non numeric inputs. Or, another example, we don't want user to forget to fill the "name" field.
In Rails, we can enforce those rules by adding validations to our model. Here's some example:
class Food < ApplicationRecord
validates :name, :description, presence: true
end
In the example above, we validate our Food model by stating that it is mandatory to have the presence of fields "name" and "description".
Next, we want to make sure that only numeric values are filled in our "price" field.
class Food < ApplicationRecord
validates :name, :description, presence: true
validates :price, numericality: { greater_than_or_equal_to: 0.01 }
end
For now, we want to make sure that we don't input foods with the exact same name because it will confuse our users.
class Food < ApplicationRecord
validates :name, :description, presence: true
validates :price, numericality: { greater_than_equal_to: 0.01 }
validates :name, uniqueness: true
end
Lastly, we want to ensure that image_url is filled with URL that ends with either ".gif", ".jpg", or ".png".
class Food < ApplicationRecord
validates :name, :description, presence: true
validates :price, numericality: { greater_than_equal_to: 0.01 }
validates :name, uniqueness: true
validates :image_url, allow_blank: true, format: {
with: %r{\.(gif|jpg|png)\Z}i,
message: 'must be a URL for GIF, JPG or PNG image.'
}
end
Now you can play with our new/edit Food form to try how these validations work.
If you go around the internet, you will find a lot of debates about on how to test. DHH himself once said that "TDD is dead".
So, not only there are many competing claims about what is the right way to use TDD in our development process, there is also the notion that TDD is not really the right way at all.
Given the circumstance, I want to highlight that for this course, we are focusing on three foundations when we do TDD:
Like most decisions, focusing on the foundations we discussed above, there will be some trade-offs in this approach to TDD:
Remember RSpec? For the rest of this project, we will use RSpec for our unit testing. Now, let's set it up. Add these lines to your Gemfile:
# -cut-
group :development, :test do
# -cut-
gem 'rspec-rails', ">= 3.4.4"
gem 'factory_girl_rails', "~> 4.4.1"
end
group :test do
gem 'faker', "~> 1.4.3"
gem 'capybara', "~> 2.4.3"
gem 'database_cleaner', "~> 1.3.0"
gem 'launchy', "~> 2.4.2"
gem 'selenium-webdriver', "~> 2.43.0"
end
# -cut-
Here are some sort explanations about the gems we just installed:
Don't forget to check if your test database is already defined in "config/database.yml" file. If not, you should set it up.
# -cut-
default: &default
adapter: sqlite3
pool: 5
timeout: 5000
# -cut-
test:
<<: *default
database: db/test.sqlite3
# -cut-
Now that everything is set and ready, fire this command in your console:
rails generate rspec:install
Lastly, modify your "config/application.rb" file:
class Application < Rails::Application
# -cut-
config.generators do |g|
g.test_framework :rspec,
fixtures: true,
view_specs: false,
helper_specs: false,
routing_specs: false,
controller_specs: true,
request_specs: false
g.fixture_replacement :factory_girl, dir: "spec/factories"
end
end