Structuring Rails applications: the Modular Monorepo Monolith
Root Insurance runs their application as a monolithic Rails application – but they've modularized it inside its repository. Here is their approach in summary:
Strategy
- Keep all code in a single repository (monorepo)
- Have a Rails Engine for each logical component instead of writing a single big Rails Application
- Build database-independent components as gems
- Thus: gems/ and engines/ directories instead of app/
- Define a dependency graph of components. It should have few edges.
- Gems and Engines can be extracted easier once nece...
MySQL: How to create columns like "bigint" or "longtext" in Rails migrations, and what :limit means for column migrations
Rails understands a :limit options when you create columns in a migration. Its meaning depends on the column type, and sometimes the supplied value.
The documentation states that :limit sets the column length to the number of characters for string and text columns, and to the number of bytes for binary and integer columns.
Using it
This is nice since you may want a bigint column to store really long numbers in it. You can just create it by ...
Render a view from a model in Rails
In Rails 5 you can say:
ApplicationController.render(
:template => 'users/index',
:layout => 'my_layout',
:assigns => { users: @users }
)
If a Request Environment is needed you can set attributes default attributes or initialize a new renderer in an explicit way (e.g. if you want to use users_url in the template):
ApplicationController.renderer.defaults # =>
{
http_host: 'example.org',
https: false,
...
}
...
Rails: wrap_parameters for your API
Rails 5 (don't know about the others) comes with an initializer wrap_parameters.rb. Here you can tell rails to wrap parameters send to your controllers for specific formats into a root node which it guesses from the controller name.
ActiveSupport.on_load(:action_controller) do
wrap_parameters format: [:json]
end
This would wrap a flat json body, like
{"name": "Konata"}
that gets send to your UsersController into
{"name" => "Konata", "user" => {"name" => "Konata"}}
Note that the params are now duplicat...
How to split config/routes.rb in Rails 4
A word of caution
There should rarely be a reason for you to split up config/routes.rb. If you need to, probably your whole application should be split up.
Split it anyway
Rails::Engine looks at config.paths['config/routes.rb'] and registers its value with app.routes_reloader. This means you could put routing files anywhere and then require them. However, I recommend to put any routing files into config/routes/:
# config/routes/example.rb
Rails.application.routes.draw do
resources :example
end
After creating y...
Riding Rails: Rails 3.0: It's ready!
Rails 3.0 has been underway for a good two years, so it’s with immense pleasure that we can declare it’s finally here. We’ve brought the work of more than 1,600 contributors together to make everything better, faster, cleaner, and more beautiful.
RailsLab .:. Scaling Rails - Scaling Rails Screencasts
Learn everything you need to know about Scaling your Rails app through 13 informative Screencasts produced by Gregg Pollack with the support of New Relic.
Building and Scaling a Startup on Rails: 12 Things We Learned the Hard Way - Axon Flux - A Ruby on Rails Blog
There are a bunch of basic functional elements to building out a popular Rails app that I've never really seen explained in one place, but we had to learn the hard way while building Posterous.
Ruby on Rails Tutorial: Learn Rails by Example | by Michael Hartl
A thorough introduction to web development with Ruby on Rails
Managing vendor assets in Rails with Bower
bower-rails is a great solution for managing vendored assets in your Rails app. It feels especially much more convenient and easier to update assets when going this way.
bower-rails generates a Bowerfile that works much like the Gemfile you're used to. Just specify your dependencies and run rake bower:install. You can find available packages here.
An example Bowerfile:
# ./Bowerfile
asset 'angular'
asset 'angular-i18n'
asset 'angular-ui-router'
asset 'angu...
When using time zones, beginning_of_day / end_of_day is broken in Rails 2 for any Date or DateTime
Using beginning_of_day or end_of_day on Date or DateTime objects in Rails 2.x applications will never respect time zones, which is horrible.\
This is fixed in Rails 3, though.
Even when using Date.current or DateTime.current you will get regular Time or DateTime objects:
>> Date.current.beginning_of_day.class
=> Time # not a ActiveSupport::TimeWithZone as expected
>> DateTime.current.beginning_of_day.class
=> DateTime ...
Nested controller routes (Rails 2 and 3)
In order to keep the controllers directory tidy, we recently started to namespace controllers. With the :controller option you can tell Rails which controller to use for a path or resource. For nested resources, Rails will determine the view path from this option, too.
That means the following code in routes.rb …
resources :users do
resource :profile, controller: 'users/profiles' #[1]
end
… makes Rails expect the following directory structure:
app/
controllers/
users/
profiles_controller.rb
users_control...
Enable NewRelic monitoring [for Rails] on specific hosts only
If you need to enable NewRelic monitoring on certain machines within the same Rails environment, a simple solution is to utilize the respective hostnames of you machines.
For example, if you have 8 application servers (e.g. app1.example.com, app2.example.com, ...) and want to enable NewRelic on app1 and app2 only, utilize those steps to do so:
- Put the attached file into your config directory (
config/custom_new_relic_configuration.rb). - Specify on which hosts NewRelic should be enabled (see
NEWRELIC_HOSTSconstant and list ...
Good real world example for form models / presenters in Rails
We have often felt the pain where our models need to serve too many masters. E.g. we are adding a lot of logic and callbacks for a particular form screen, but then the model becomes a pain in tests, where all those callbacks just get in the way. Or we have different forms for the same model but they need to behave very differently (e.g. admin user form vs. public sign up form).
There are many approaches that promise help. They have many names: DCI, presenters, exhibits, form models, view models, etc.
Unfortunately most of these approaches ...
markbates/coffeebeans
When CoffeeScript was added to Rails 3.1 they forgot one very important part, the ability to use it when responding to JavaScript (JS) requests!
In Rails 3.1 it’s incredibly easy to build your application’s JavaScript using CoffeeScript, however if you fire off an AJAX request to your application you can only write your response using regular JavaScript and not CoffeeScript, at least until CoffeeBeans came along.
Ruby, Rails, Web2.0 » Blog Archive » Great Ruby on Rails REST resources
I have been playing around with RESTful Rails recently. Below is my collection or Rails REST howtos, tutorials and other resources I have found so far.
iPhone on Rails and ObjectiveResource; Making communication between the iPhone and a Rails web-service pain-free.
ObjectiveResource is an Objective-C port of Ruby on Rails' ActiveResource. It provides a way to serialize objects to and from Rails' standard RESTful web-services (via XML or JSON) and handles much of the complexity involved with invoking web-services of any language from the iPhone.
Ruby on Rails » Keeping Up With The Joneses: Keeping Rails and its extensions up to date » Pathfinder Development
There are many wonderful things about Rails and the Rails ecosystem. A clean, well-lighted path for keeping all your extensions up to date is not one of them.
Rails: Default generators
This is a visualization of the files that will be generated by some useful rails generators. Invoke a generator from command line via rails generate GENERATOR [args] [options]. List all generators (including rails generators) with rails g -h.
| generator | model | migration | controller | entry in routes.rb
|
views | tests |
|---|---|---|---|---|---|---|
| scaffold | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| resource | ✔ | ✔ | ✔ ... |
How to fix "undefined method `name' for Array" error when running bundled commands on Ruby 1.8.7 + Rails 2.3
On recent/fresh installations of Ruby 1.8.7 you may encounter this error why calling any bundled binary (or just bundle exec):
/home/arne/.rvm/gems/ruby-1.8.7-p374@global/gems/rubygems-bundler-1.4.2/lib/rubygems-bundler/noexec.rb:75:in `setup': undefined method `name' for #<Array:0x7fe04783ef30> (NoMethodError)
from /home/arne/.rvm/rubies/ruby-1.8.7-p374/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:29:in `map'
...
Apparently, this is due to bundler (or maybe the rubygems-bundler that RVM supplies by default) no lon...
Rails 3 routing: Be careful with matching routes *including their format*
Today, this line made me trouble. Can you spot the mistake?
match 'sitemap.xml' => 'feeds#sitemap', :constraints => { :format => 'xml' }, :as => 'sitemap'
The mistake is to match sitemap.xml. Rails will by default strip any dot-anything, remember it as desired format and forward the rest of the request to the routing engine. Since we're making .xml part of the match, it is not available for format determination and Rails will set the format to html.
Unfortunately, the constraint won't complain in this case and Rails even ren...
Installing Rails on a fresh system
- Install Ruby from the Ubuntu repository:
sudo apt-get install ruby ruby-dev\
rubyis the meta package. If you want to explicitly install 1.8 or 1.9, installruby1.8orruby1.9instead (the same applies forruby-dev). - Do not install RubyGems from the repository but install the version from the webpage instead.
- Get Bundler:
sudo gem install bundler
Rails and other gems for a project should now be installed via bundle install from the...
Rendering a custom 404 page in Rails 2
Simple: Tell the application controller how to handle exceptions, here a RecordNotFound error.
Do this with the following line:
# application_controller.rb
rescue_from ActiveRecord::RecordNotFound, :with => :render_404
This will call the method render_404 whenever a RecordNotFound error occurs (you could pass a lambda instead of a symbol, too).
Now write this method:
def render_404
render 'errors/404', :status => '404'
end
Finally create a 404 document views/errors/errors.html.haml.
%h1 Record...
Custom loggers in Ruby and Rails
File logger
If you need to log to a file you can use Ruby's Logger class:
require 'logger'
log = Logger.new('log/mylog.log')
log.info 'Some information'
log.debug 'Debugging hints'
log.error StandardError.new('Something went wrong')
Logger does a number of things well:
- Message type (info / debug / error) is logged
- Log entries are timestamped
- Writing log output is synchronized between threads
- Logged errors are printed with full backtraces
If you don't like the output format, you can define a custom formatter.
I ha...