Channels
Posted 2 days ago at The Life of a Radar

I gave a presentation at SpreeConf and Ruby on Ales about engines.

I recorded it again at home last week and You can watch/download the video here. It’s a little over 30 minutes long, but I think it teaches you valuable lessons about engines in Rails.

back to top
Posted 23 days ago at The Life of a Radar

I used to drink a lot of Coca Cola. I think my record was 18 375ml cans of it during a LAN party once. I didn’t feel so good the morning after. I used to not brush my teeth that often as well (compared with now, which is morning & night as all good dentists recommend), and as a result I have very “holey” teeth and even had one extracted in February. I used to drink Coca Cola because it contained caffeine which would give me a pleasant buzz.

Then my dentist suggested that I stop drinking drinks containing that much sugar, and so I did. I switched to Pepsi Max for a couple of years after that. Then, one day, I stopped. I can’t remember the exact reason why I stopped drinking it, but I did. This was back in 2009.

The first couple of days were interesting. I had trouble focussing for long periods of time. I never got the caffeine headaches that people talk about. But then it got gradually better and I’ve been basically caffeine-free for close to 3 years now. Then it kept getting better. I found myself sleeping more solidly each night and being able to concentrate for longer and longer periods. I very rarely now have moments where I feel completely exhausted. When they do happen, having a some sugar helps for that last little bit.

Then there was the change in sleeping pattern in 2010, when I started writing Rails 3 in Action. I swithced from getting up at 7:45am to getting up at 6:00am. And I did this every day, except where I stayed out late the night before. That extra time in the morning allowed me to do some internet catch up, do some writing, have a shower and get ready for the day and then still have more time to do even more writing. After a late night out, there’s that buffer there that I can use to catch up on sleep that I’ve otherwise missed. I can also use this time for exercise, which is awesome.

When I get to work it’s no longer just over an hour since I woke up. It’s more like three hours. With me not being a morning person by nature, this is wonderful. I come in to work and I’ve already woken up fully and I can just get to doing everything.

Tim Riley wrote about his experiences with getting up earlier too.

However, I’ve found this new approach to be very effective. The early mornings are a good time. It is quiet. The day has just begun and my mind is clear of any distractions, so it is easy to concentrate. Because the time for work has a definite ending, it also encourages me to pick discrete and achievable goals for each morning. Rinse and repeat, and before long, I have demonstrable, consistent, incremental progress towards my goal.

So, my thing I want you to try is to go the whole month of May by changing one of these two habits. Either cut out caffeine completely from your diet, or start getting up early in the morning. If you want the “Hard Mode” variety, try both. It’s really improved my life and I reckon it’ll do the same to yours.

back to top
Posted 24 days ago at The Life of a Radar

I gave a lightning talk at Railsconf in response to a talk done by Andy Maleh about engines. His talk contained some content that I strongly disagreed with, and so I felt it necessary to set the record straight. You can see the slides for it here. I will have a more thorough dissection of the talk once the video is online.

To be perfectly honest, I am probably bitter because I was going to submit a talk about engines and then decided to submit another talk instead which ultimately didn’t get accepted. Nevertheless…

Drawing routes

The first thing that I can recall disagreeing with is Andy’s suggestion to draw routes for the engine on the Rails.application.routes object, by putting this code inside the config/routes.rb file of the engine:

Rails.application.routes.draw do
  resources :people
end

The problem with this is that if the application’s routes file has a catch-all route at the bottom, the route for the engine won’t get matched because it is drawn after the application.

This leads to additional complexity as well, as by drawing these routes on the application like this, they would also correspond to a controller that’s at the top-level of the namespace, i.e. PeopleController. This can lead to confusion as to where the controller is located. How can someone know if PeopleController is inside the engine or is inside the application? Furthermore, the more engines that get added to this application, the more confusing such a thing would get.

By namespacing the routes properly (as we do in Spree and Forem) , like this:

Spree::Core::Engine.routes.draw do
  resources :products
end

And by using isolate_namespace inside your engine, the routes will be a completely separate entity for each engine, rather than one big “ball o’ mud”. In Spree this namespace isolation is to the Spree module (i.e. isolate_namespace Spree), so that the controllers will be Spree::ProductsController and not Spree::Core::ProductsController and the like.

By using a completely isolated namespace like this, your controller would end up being correctly namespaced and then there’s no confusion as to which engine the controller is located within. You can then mount your engine at whatever path you want inside your application by explicitly defining the mount point inside config/application.rb like this:

mount Spree::Core::Engine, :at => "/"

By mounting it at root, it will seem as if the engine were a part of the application itself. If you wanted to change where the engine was mounted, it’s a simple matter of changing the :at: option and you can carry on like normal.

There’s a whole bunch of other stuff that isolate_namespace does as well, like namespacing of models and tables. It’s absolutely important that you namespace your engine to avoid confusion.

Oh, and one more thing: by doing this namespacing, if you want to get to an engine route from inside the application, you’ll need to call the engine’s routing proxy method, like this:

spree.products_path

If you attempted to do products_path it would go to the application’s products_path, which may be undefined.

Similarly, to get to the application’s routes from inside the engine, use main_app:

main_app.people_path

Switching back and forth

The second thing that I disagreed with during Andy’s talk was that he said that when developing an engine you needed to constantly switch back and forth between the application and the engine. This is simply not true. If you are developing your engine correctly, the development of it can be done in complete isolation from a real application and instead depend on a dummy application. It should not be a requirement for you to have two separate projects coupled together like this so you can test one or the other.

How we do it in Forem is that we have a dummy application inside spec/dummy which is generated by running bundle exec rake forem:dummy_app. This command creates a new dummy application with things like User model already set up inside it. Inside Spree, there’s a similar command called bundle exec rake test_app which does basically the same thing.

With the dummy application inside the engine, the engine is mounted onto that application and the tests are then run against that application. No need to switch back and forth from application to engine.

If you have modifications for the engine inside your application, there’s also a way to test that. With Spree, we provide a module called Spree::Core::UrlHelpers that you can include into your RSpec.configure block like this:

require 'spree/core/url_helpers'
RSpec.configure do |c|
  c.include Spree::Core::UrlHelpers, :type => :integration
end

Then in your integration tests it’s simply a matter of referencing the Spree routes like this:

visit spree.products_path

Now for when you want to test that a customization to a Spree controller is behaving as intended, we’ve got a module for that too. It’s called Spree::Core::TestingSupport::ControllerRequests and you can include it like this:

require 'spree/core/testing_support/controller_requests'
RSpec.configure do |c|
  c.include Spree::Core::TestingSupport::ControllerRequests, :type => :controller
end

Then you can write your controller specs like this:

describe Spree::ProductsController do
  it "can see all the products" do
    spree_get :index
  end
end

This will then allow you to make requests to the Spree engine from inside your application’s tests.

Conclusion

There’s absolutely no reason to mount engine routes directly on Rails.application.routes, nor is there a requirement to switch back and forth. Integration testing an engine is extremely easy once you know how to do it.

back to top
Posted about 1 month ago at github

m lib/booki/editor/templates/authors.html
Update lib/booki/editor/templates/authors.html

back to top
Posted about 1 month ago at github

m lib/booki/reader/templates/reader/draft_chapter.html
Update lib/booki/reader/templates/reader/draft_chapter.html

back to top