Most Ruby on Rails developers don’t test their routes, they focus on Model testing, Controller testing, Features or View testing, Helper testing, and try to catch every possible scenarios. I would like to show how to test route separately.
Sample routes.rb:
routes.rb
1
resources:products
Here is routes lists thats have been created:
12345678
root/products#indexpostsGET/products(.:format) products#index POST /products(.:format)products#createnew_postGET/products/new(.:format)products#newedit_postGET/products/:id/edit(.:format)products#editpostGET/products/:id(.:format)products#showPUT/products/:id(.:format)products#updateDELETE/products/:id(.:format)products#destroy
Testing for each routes in routing/products_routing_spec.rb:
require'spec_helper'describe"routing to products"doit"routes /products to products#index"doexpect(get:"/products").toroute_to(controller:"products",action:"index")endit"routes /products/1 to products#show"doexpect(get:"/products/1").toroute_to(controller:"products",action:"show",id:"1")endit"routes /products/new to products#new"doexpect(get:"/products/new").toroute_to(controller:"products",action:"new")endit"routes /products to products#create"doexpect(post:"/products").toroute_to(controller:"products",action:"create")endit"routes /products/1/edit to products#edit"doexpect(get:"/products/1/edit").toroute_to(controller:"products",action:"edit",id:"1")endit"routes /products/1 to products#update"doexpect(put:"/products/1").toroute_to(controller:"products",action:"update",id:"1")endit"routes /products/1 to products#destroy"doexpect(delete:"/products/1").toroute_to(controller:"products",action:"destroy",id:"1")endend
Testing unroutable:
routes.rb
1
resources:products,except:[:show]
products_routing_spec.rb
123
it"does not routes /products/1 to products#show"doexpect(:get=>"posts/1").not_tobe_routableend
So far so good, Let enjoy the routes testing in your Ruby on Rails application. :)
RailsPanel is a Chrome extension for Rails development that will end your tailing of development.log. Have all information about your Rails app requests in the browser - in the Developer Tools panel. Provides insight to db/rendering/total times, parameter list, rendered views and more.
Installation
To use this extension you need to add meta_request gem to your app’s Gemfile:
Gemfile
123
group:developmentdogem'meta_request'end
Install RailsPanel extension from the Chrome WebStore. This is recommended way of installing extension, since it will auto-update on every new version. Note that you still need to update meta_request gem yourself.
So far so good, Let play around with RailsPanel and enjoy your productivity. :)
Ruby on Rails is an awesome framework to build web application. Rails relies on the MVC pattern, and lots of conventions, code becomes complex to maintain, productivity start to decrease, etc.
We can find a lot of reasons to this(too much logic in controllers, fat models, lack of services layers, etc.), but I will just name one: logic in view, logic in view is bug prone, difficult to test, and can be a pain for front-end developers.
Well, you got it, logic in view. And since rails don’t have view inheritance, this code will have to be copy-pasted over and over, I would rather have something like: = @article.link_to_edit
So, how can we remove logic from the view?
Decorator Design Pattern save the views
As usual, we can find a solution with a pattern. the decorator design pattern will help us remove logic from views in our Rails applications.
The idea is to insert an object between the model and the view, well there is a good ruby gem is Draper that work well.
A few things to notice here. From the controller, we call the decorate method on a instance of article, this will return a decorated version of the article object.
In the ArticleDecorator class, we have access to the decorated object with the object method and to all view helpers through the h object.
We can now call the link_to_edit method on the article object from our view, and the decorator will take care of the logic, and return a formatted link if the user has the right edit this resource, and nothing if he does not.
The code is easier to test, we just instantiate a new instance of the ArticleDecorator, and check the output of the link_to_edit method. No need to test whole renderd view, searching through the DOM object tree.
So far so good, we gain code readablility, code reuse, better testing, and in addition, we even lost a few lines of duplicated code. :)
Vim is an advanced text editor that provide the power of Unix editor ‘Vi’, with a more complete feature set.
Vim is a highly configurable text editor built to enable efficient text editing. It is an improved version of the vi editor distributed with most UNIX systems.
Vim is often called a “programmer’s editor,” and so useful for programming that many consider it an entire IDE. It’s not just for programmers, Vim is perfect for all kinds of text editing, from composing email to editing configuration files.
Features
- highly configurable.
- syntax highlightning.
- windows split (both vertically as well as horrizontally).
- tabbing.
- folding.
- unicode support.
- flexible indenting.
- …
The Good
Vim is a professional text editor targeting mainly programmers, but it can be also used by any other type of user.
It received the best text editor award from readers of the Linux Journal magazine in 2001, 2002, 2003 , 2004 and 2005, which I think tells a lot about its efficiency.
The Bad
The bad and ugly part about Vim would be for most users the fact that they must do the learning first in order to be able to use it.
The Truth
Vim is a multi-platform text editor, Vim provides all the functionality of a regular text editor, such as spell checking, Unicode support, possibility of undo/redo the most recent actions, integrated help but it has also some features of its own which make it a powerful and reliable tool.
So far so good, To get a better idea on what Vim is, you can also check www.vim.org :)
In the object-oriented world, simple applications usually require small classes with static behaviors. Adding, modifying, and sharing those behaviors can be achieved by mixing in modules or inheriting from other classes at compile time.
However, more complex applications might require a particular instance of a class to gain additional functionality at runtime. To modify the behavior of an object dynamically, we can utilize the decorator design pattern.
When to Decorate
Decoration can be used to add behavior to any individual object without affecting the behavior of other objects of the same class. Essentially the existing object is being wrapped with additional functionality.
Some practical problems that can be solved by decoration are
- applying one or more UI elements to a specific UI widget at runtime.
- saving an ActiveRecord model in various ways based on conditionals in a Rails controller.
- adding additional information to data streams by pre/appending with additional stream data.
Implementations of Decorators in Ruby
There are several ways to implement the decorator pattern in Ruby, but I cover my 4 favorite ways:
- Class + Method Missing decorator
- Module + Extend + Super decorator
- Plain Old Ruby Object decorator
- SimpleDelegator + Super + Getobj decorator
Class + Method Missing Decorator
The benefits of this implementation are:
- can be wrapped infinitely using Ruby instantiation.
- delegates through all decorators.
- can use the same decorator more than once on the same component.
- transparently uses component’s original interface.
The drawbacks of this implementation are:
- uses method_missing.
- the class of the decorated object is the decorator.
Module + Extend + Super Decorator
The benefits of this implementation are:
- it delegates through all decorators.
- has all of the original interface because it is the original object.
The drawbacks of this implementation are:
- can not use the same decorator more than once on the same object.
- difficult to tell which decorator added the functionality.
Plain Old Ruby Object Decorator
The benefits of this implementation are:
- can be wrapped infinitely using Ruby instantiation.
- delegates through all decorators.
- can use same decorator more than once on component.
The drawbacks of this implementation are:
- cannot transparently use component’s original interface.
SimpleDelegator + Super + Getobj
The benefits of this implementation are:
- can be wrapped infinitely using Ruby instantiation.
- delegates through all decorators.
- can use same decorator more than once on component.
- transparently uses component’s original interface.
- class if the component.
The drawbacks of this implementation are:
- it redefines class.
Ruby on Rails is a popular web framework written in Ruby. In this artical covers using Rails 4 on Heroku. The many step for deploying Rails 4 to Heroku below:
1. Installation heroku environment (www.toolbelt.heroku.com) – if you not yet have
Open your terminal and type command below:
Rails 4 requires Ruby 1.9.3 or above. Heroku has a recent version of Ruby installed, however you can specify an exact version by using the ruby DSL in your Gemfile by adding ruby “2.1.1” at the end of Gemfile.
ruby "2.1.1"
4. Deploy to heroku
Open your terminal and type command below:
While a lot of techniques and libraries have come and gone as the community’s preferred way of doing something, there are some best practices that remain, and can lead to writing the clean code, most secure and maintainable Ruby on Rails code possible.
Listed here there are the most popular and useful best coding you can use as a Ruby on Rails developer:
Fat Model - Thin Controller
The most important ways to write clear and concise cod in Ruby on Rails is “Fat Model - Thin Controller”. Model and Controller are parts of MVC(Model - View - Controller), many logic should go in the Model, and Controller is a nice interface between the view and Model.
In priactice, We should move any logic that isn’t about the response(setting a flash message, redirect, render view) to the model instead of the controller, anyway we can reuse it where possible and make it possible for testing outside of the Controller.
Let look at sample example we have code in brands_controller.rb:
With the methods Brand.find_brands_by_category, we’ve not only made it simpler to test our code, we’ve also made it possible to reuse that same set of conditions in another location. But as we’ll see shortly, even this is still not ideal.
Reusable Scopes and Relations
Ruby on Rails provides a better way – scopes to avoid duplication condition in another methods.
Let look at sample example we have code in brands.rb:
Virtual Attributes
If you find that you’re manipulating data before passing it to a model (for example, converting the type of an object), it’s likely time you started structuring your code to take advantage of virtual attributes.
Virtual attributes are a very simple idea—essentially, all you’re doing is defining your own getter and setter methods.
Use the Built-in Ruby Duck Typing Methods
Ruby uses several conventions that can make development easier like implementing a to_s instance method on an object will give you a standard way of getting a string representation of your object.
By implementing these standard type conversions—in addition to to_s, there’s also to_i for integers, let have a look at the following string interpolation:
brand.rb
1
"Hello there, #{user.name}"
Use Non-database-backed Models
Although models in Rails are mostly based on ActiveRecord::Base or some other type of object mapper for a database, it’s important to remember that in MVC, the M isn’t restricted to database-backed models.
Using non-database-backed models can help to organize logic which might otherwise become muddy. For example, there are libraries that give you anActiveRecord-like interface for contact form emails.
When it comes time to interact with these models in your controller code, your code will be that much cleaner, as you can use the exact same approach as with database-backed models.
Package Your Code into Gems
I you’ve used Ruby on Rails, you’ve noticed the wealth of rubygems available to Rails developers.
When you write code you think is general enough—which usually just means you’ve written it more than once before in another application, let extract it into a gem suitable for a wider range of purposes.
So far so good, there are hundreds of coding practices or techniques that can make your life as a Ruby on Rails developer easier, but I’ve tried to pick out some. :)
1. rails-footnotes
Description: This gem allows you to display footnotes in your application on pertinent information such as database queries, request parameters, etc. You can also create your own custom footnotes for objects in your application.
Helping: It’s helpful for debugging your application and showing you how long your database query took.
Source: https://github.com/josevalim/rails-footnotes
2. bullet
Description: This gem watches your database queries and alerts you when it thinks you should use eager loading, when you’re using eager loading unnecessarily, and when to consider using counter cache.
Helping: Unnecessary database queries slow down your application’s performance. Using eager loading and counter cache are two easy things you can implement for a performance boost. For high traffic websites, database queries can be the bottleneck for performance.
Source: https://github.com/flyerhzm/bullet
3. request-log-analyzer
Description: This gem outputs a performance report based on your application’s database request log file(s). It includes metrics such as average server time (the average time a server needs to respond to a user request) and cumulative server time (the sum of all the server time needed to handle all the requests for a given action on the server, i.e., the “load” on a server).
Helping: It uses your log files to tell you how your server is responding to database requests and points you in the direction of code to optimize in your application.
Source: https://github.com/wvanbergen/request-log-analyzer
4. ruby-prof
Description: This is a code profiling tool for MRI ruby implementations. It can generate graphical reports and gives information on call times, memory usage, and object allocation.
Helping: It can help you figure out where your “slow code” is in your rails application.
Source: https://github.com/ruby-prof/ruby-prof
5. rack-mini-profiler
Description: This is originally a .NET tool ported over to Ruby that displays a speed profile badge on each html page you navigate to.
Helping: If a page feels “slow”, MiniProfiler can give you a good idea of where the bottleneck is. It also lets you know which “sessions” you have not seen and displays them to you the next time you access your user interface. It allows you to easily see how much time you’re spending on database queries versus other non-SQL related bottlenecks.
Source: https://github.com/MiniProfiler/rack-mini-profiler
With strong_parameters becoming the standard way of handling security in Rails 4, I played around with it. It works great except the documentation isn’t clear on how to handle nested forms inside Rails, specifically with the accepts_nested_attributes_for in the model and fields_for in views.
So far so good, let take a look a short example below.
classAccountsController<ApplicationControllerdefnew@account=Account.new@account.people.buildenddefcreate@account=Account.new(new_account_params)if@account.saverespond_todo|format|format.html{redirect_toroot_path,notice:"Account created successfully."}endendendprivatedefnew_account_paramsparams.require(:account).permit(:id,:name,people_attributes:[:id,:email,:password,:password_confirmation])endend