Sometimes it’s hard to remember model attributes and relationships between them. Especially when you are new to the project, diagrams can be very helpful. I came across Railroad gem when I was searching for the right tool. It can generate controller diagrams with inheritance hierarchy and model diagrams with attributes and associations. Output is in the DOT language. Generated .dot files can by processed by Graphviz into .svg or .png format. If you have Omnigraffle you can import .dot files and edit them.
Easy method to cut string to a defined length without leaving words cut in half.
[sourcecode lang=”ruby”]class String
def truncate_full_words limit = 64, completion = “…”
self.length > limit ? “#{self[0..(self.rindex(’ ‘, limit) || limit)-1]}#{competion}” : self
end
def truncate_full_words! limit = 64, completion = “…”
self.replace(self.truncate_full_words limit, completion)
end
end[/sourcecode]
Usage:
[sourcecode lang=”ruby”]» some_string = “Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum nec enim nibh.”
=> “Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum nec enim nibh.”
» some_string.truncate_full_words
=> “Lorem ipsum dolor sit amet, consectetur adipiscing elit. …”[/sourcecode]
Have fun using it :)
In one of our rails projects, we found that a lot of models needed some sort of unique token or guid generated before saving. Most of them were then used in routes or something similiar, but all of them were generated by callbacks in each model. Since that methods were mostly effect of copypasta, i decided to abstract the code, and make a plugin of it.
A bit of meta programming later, i’m proud to present the results: http://github.com/netguru/has_uniq_token/
Hope you find it useful.
Today we needed to make a tool to convert Microsoft Office (and preferably other formats) documents to PDF from a Rails application. We have come up with such solution - install OpenOffice.org, CUPS and CUPS-PDF (virtual PDF printer for CUPS) and run it like this:
soffice -headless -pt Cups-PDF file.doc
This command executes OpenOffice.org in so-called ‘headless’ mode - meaning that it will not run anything graphical. It reads the file.doc, and prints it using CUPS-PDF virtual printer. The resulting PDF can be found (by default) in ~/PDF directory.
That’s pretty basic stuff but if you wonder how to validate email in rails check out this plugin:
http://github.com/dancroak/validates_email_format_of/
Good luck.
Fastest way to use sql dump when riding Ruby On Rails.
script/dbconsole < dumpname.sql
Define:
[sourcecode lang=”ruby”]
class Array
def every_nth(nr)
self.in_groups_of(nr).map(&:first)
end
def every_nth!(nr
self.replace(self.every_nth(nr))
end
end
[/sourcecode]
and use:
[sourcecode lang=”ruby”]
» (1..9).to_a.every_nth(3)
=> [1, 4, 7]
[/sourcecode]
Suppose that you implemented a functionality that depends on values of created_at or updated_at fields of your models. How do you test it?
If you use fixtures that reside in test/fixture/*.yml files then there is no problem, because the values you set there for created_at and updated_at fields are saved to the database ‘as is’. So you can easily have an article created one week ago:
[sourcecode lang=”yml”]article:
title: What a great day
created_at: < %= 1.week.ago.to_s(:db) %>
updated_at: < %= 1.week.ago.to_s(:db) %>
[/sourcecode]
However, I don’t use fixtures files myself. I feel a bit dirty using them ;) I find fixture replacement tools far more maintainable. Namely, I love thoughtbot’s Factory Girl. But here comes the problem. This won’t work as expected with Factory Girl:
[sourcecode lang=”ruby”]
Factory(:article, :created_at => 1.week.ago, :updated_at => 1.week.ago)
[/sourcecode]
That’s because ActiveRecord’s automatic timestamping feature sets Time.now for created_at and updated_at fields overriding our values. At least that’s ActiveRecord’s default behavior. Fortunately it can be disabled with:
[sourcecode lang=”ruby”]
Article.record_timestamps = false
[/sourcecode]
Chances are that after creating a model with a custom timestamp we’ll want to turn automatic timestamping back on. But turning it off and on in many places in your unit tests would be pretty cumbersome. Wouldn’t it be cool if you could achieve all of this with a snippet below?
without_timestamping_of Article do
Factory(:article, :created_at => 1.week.ago, :updated_at => 1.week.ago)
end
It turns timestamping off, executes the block and turns timestamping back on. I find it clean and dry. Here’s the code to place in your test_helper.rb:
[sourcecode lang=”ruby”]
# test_helper.rb
class Test::Unit::TestCase # or class ActiveSupport::TestCase in Rails 2.3.x
def without_timestamping_of(*klasses)
if block_given?
klasses.delete_if { |klass| !klass.record_timestamps }
klasses.each { |klass| klass.record_timestamps = false }
begin
yield
ensure
klasses.each { |klass| klass.record_timestamps = true }
end
end
end
end
[/sourcecode]
Hope you like it. If so, share :)
Handling sessions in multi-domain environment is not the simplest things to do, because of the fact that cookies are scoped to a domain they were set by.
Recently we were developing an application with such an idea in mind:
- Application will work as a base for other mini-applications (which we call sites)
- Each site can be accessed via different url types: site.example.org and example.org/site
- We want the users to remain logged in when switching from one url type to another
I won’t be covering application structure, routing, etc. here, I will only write about maintaing the sessions is such an environment.
So this is pretty simple here - all that we needed to do was to set cookie domain to .example.org (note the “dot” at the beginning). This could be done via:
[sourcecode lang=”ruby”]ActionController::Base.session = {
:domain => “.example.org”
}[/sourcecode]
However there was an additional requirement that we need to deal with:
- Each site can be accessed via custom domain - site.com
- Of course there’s no way here to keep the user logged in when he’s switching from site.com to example.org/site or site.example.org, at least it cannot be done with setting cookie domain to whatever value
Technically, to access the site via site.com, that domain must point to our IP address. Then we need to detect that the site is being accessed via custom domain and set cookie domain respectively.
This could be done via some funky before_filters in an Application Controller, however we found much better and cleaner way.
Rack’s middleware to the rescue
Rack itself is a minimal interface between web server and your ruby framework. It’s used by Ruby on Rails (since 2.3) and Merb. The request comes from web server, goes through middleware layers and enters the application.
So we wrote a middleware layer that detects the host with which our application is accessed and sets cookie domain for the request. Here it is:
app/middlewares/set_cookie_domain.rb
[sourcecode lang=”ruby”]class SetCookieDomain
def initialize(app, default_domain)
@app = app
@default_domain = default_domain
end
def call(env)
host = env[“HTTP_HOST”].split(‘:’).first
env[“rack.session.options”][:domain] = custom_domain?(host) ? “.#{host}” : “#{@default_domain}”
@app.call(env)
end
def custom_domain?(host)
domain = @default_domain.sub(/^./, ”)
host !~ Regexp.new(“#{domain}$”, Regexp::IGNORECASE)
end
end[/sourcecode]
Now we need to turn it on:
environment.rb
[sourcecode lang=”ruby”]config.load_paths += %W( #{RAILS_ROOT}/app/middlewares )[/sourcecode]
production.rb
[sourcecode lang=”ruby”]config.middleware.use “SetCookieDomain”, “.example.org”[/sourcecode]
.example.org is the default domain that will be used unless the application is accessed via custom domain (like site.com), we give it different values depending on environment (production/staging/development etc).
And since we’re fans of test driven development, here’s the test that ensures us that everything works as expected:
tests/integration/set_cookie_domain_test.rb
[sourcecode lang=”ruby”]require ‘test_helper’
class SetCookieDomainTest < ActionController::IntegrationTest
context “when accessing site at example.org” do
setup do
host! ‘example.org’
visit ‘/’
end
should “set cookie_domain to .example.org” do
assert_equal ‘.example.org’, @integration_session.controller.request.session_options[:domain]
end
end
context “when accessing site at site.com” do
setup do
host! ‘site.com’
visit ‘/’
end
should “set cookie_domain to .site.com” do
assert_equal ‘.site.com’, @integration_session.controller.request.session_options[:domain]
end
end
context “when accessing site at site.example.org” do
setup do
host! ‘site.example.org’
visit ‘/’
end
should “set cookie_domain to .example.org” do
assert_equal ‘.example.org’, @integration_session.controller.request.session_options[:domain]
end
end
end[/sourcecode]
Test is sponsored by great Shoulda and Webrat gems.
Feel free to comment and share.
Taken from Ryan’s blog:
Ryan Daigle is an independant developer working as Y|Factorial, LLC, a ruby and iPhone software consultancy.
He also writes Ryan’s Scraps, the “What’s new in edge rails” blog.
Bartosz Pietrzak: Which OS and which editor are you using?
Ryan Daigle: I’m on Mac OS X which means that I use Textmate for most of my work.
Do you prefer GIT or SVN?
I prefer GIT, although I’m not a GIT master, but I do prefer it.
Do you see any upsides or downsides of using GIT, comparing it to SVN?
Well, certainly there are a lot of benefits, like easy branching, low cost branching and things of that nature. As far as downsides, I think it’s more complex tool, so it takes a little more effort to become very efficient at it, but that’s hardly a downside. It just means that it might require a little more effort to become good at using that tool.
What plugins or gems do you usually generate your new apps with?
Let’s see… I use HAML, make resourceful, rspec, cucumber, all those gems. Let me open up one of my projects right now. Will_paginate, HAML and make resourceful - these are the core ones that I tend to at least start with.
What’s your strategy for populating your database with some predefined data? Do you use migrations, fixtures, rake tasks with gems like populator?
For staging data, for data that I just want to populate the database to play with the app I usually have a rake task that use something like factory girl or, there’s a plugin I highly recommend, called dataset, which is a fixture replacement, but it lets you load predefined set of data with one rake task. So I use that for staging data and if it’s setup data, configuration data for the application that needs to be present in production and staging, then I usually write a custom rake task, but the point being I keep it out of my migrations, because I don’t think that migrations are the place to do data population. Migrations are place to alter the structure of your database and occasionally, in the course of altering the structure of the database you do need to tweak or change something, but as for data population I keep it out of my migrations.
What is your opinion on TDD?
My opinion is that it’s great and it’s certainly what I choose to use to start things off. There are many different tools that you can use in TDD but as far as general methodology is concerned I certainly am keen on it.
You’ve mentioned Rspec. What do you think about Shoulda?
I’ve obviously heard about Shoulda, Mocha and they seem to have good reputation, I’d just not had the least recognition needed to anything other than rspec, so I’m still using rspec and haven’t really looked into the others. Although recently I started doing Cucumber, Webrat and rSpec, it’s kinda my testing stack and I’ve enjoyed that process.
How do you think Rails development process will change after 3.0 release?
Oh, that’s a tough one! I mean, I’ve not seen much actual work come through on the Rails source on github so it’s hard to say if most of the changes will have limited external effects and mostly just internal tweaks and refactorings, although I think one of the stated goals will be to make rails a little more componentized, a little more accessible without of monkey patching rails classes to overwrite functionality and add new functionality, I think they gonna try to give you more predefined points at which you can hook into their functionality, so I think for plugin writers and gem writes and engine writers I think the development process will be a lot cleaner and a lot more stable, as far as everyday developers I’m not quite sure yet how they’ll be impacted.
What usually do you do with your team first, design of the applications or the you know, code and the functionality of the applications?
When you say design, do you mean visual design?
Yes.
Ok, so usually when I start on a project I like to have at least wireframes in place so I like for my client to have at least thought about the functionality that their users will see, but I don’t necessarily want the visual design in place, I don’t need to see fonts, sizes and colors and pretty graphics, I just need to know how the client’s envisioning their functionality will be exposed to the user. And then when I start on, my preference is to have visual design kinda be done in parallel, or at least maybe week or two in front of development, I feel like if you treat visual design and development as two separate deliverables, then often in the end, when you try to bring those two sides together there’s a lot of work that goes into melding the two, so if you can treat it as one highly integrated process throughout your outcome will be much better. So, in the beginning I do like to see a visual representation of the functionality that needs to be developed, but I don’t need to see a visual design.
Do you prefer the getting real way of creating the applications or huge specifications?
Well, certainly I’m against huge specs of any kind, so I would have to come down on the side of getting real, I feel like not everybody has a luxury of such a freeform process as getting real, but certainly the main tense of that thought process I do support.
These will be private ones, do you prefer working from home or from office?
I think there are definitely benefits to an office, but I think if you are working with a group of people that you’re familiar with, and you know their work style, and you trust the work they do I think working from home can be more productive since you’re outside of the realm of those frequent interruptions that happen in office and really let you be quite productive, so I think for my productivity sake I enjoy working from home and occasionally it makes sense to get together to discuss something in person, but for the majority of the time I think working from home is beneficial.
Do you prefer night time or day time and what about separating work from private life?
I’m not a morning person but I start my day pretty early, because I like to have my work done somewhat early, so that I can have the late afternoon and evenings for myself, for personal time, so come 4:30 or 5 o’clock I usually, you know, I don’t turn off my computer but I put it away wherever I go, go running, go to the gym or do something like that and force myself to get out of the house and that’s serves as my formal break between work time and personal time. And then the weekend it’s the same thing, I don’t really feel compelled to go to my home office and start working on the weekends, it’s just structured that way, so I don’t really think about that. It doesn’t mean everything’s done during the week. Maybe I’ll just fire off some emails, but I don’t really get into core work mode during personal time.