If you execute IRB with the command line flag –noprompt you will enter in to an IRB session with none of the extra characters showing up on the left side of the terminal. This is great if you want to experiment with code and then use the mouse to copy & paste from it. Like, for example, in a code blog like the one you’re reading…
(Thanks to 6ftdan for this cool tip.)
Spaghetti Refactory
Monday, February 22, 2016
Monday, February 15, 2016
Rspec tricks for DRY mocked specs
These “tricks” are straight from the docs. One will help DRY up your specs, the other will help you mock your controller for controller tests.
First, define your shared context:
Then, include it in your spec files:
Shared Contexts
Shared context allows for extracting certain setup steps and sharing them across several different sets of tests.First, define your shared context:
RSpec.shared_context "user setup" do
let(:user) { User.new(name: 'Chuck Norris') }
before { allow(user).to receive(:some_method) }
end
Then, include it in your spec files:
describe UsersController do
include_context 'user setup'
# Tests go here...
end
Anonymous Controllers
Anonymous controllers are a way to specify certain behavior for the controller you are trying to test, or more likely for a parent controller. The thing I found it most useful for, and not coincidentally the thing that the docs says it is useful for, is testing global error handling.
describe UsersController do
controller do
def index
raise AccessDenied
end
end
subject { get :index }
describe "handling AccessDenied exceptions" do
it "redirects to the /401.html page" do
expect(subject).to redirect_to("/401.html")
end
end
end
Monday, February 8, 2016
Converting unix timestamps in Ruby
Unix timestamps are common to see in other languages, and also common to see in API responses. Converting a unix timestamp to DateTime in Ruby is dead simple:
Let’s say your unix timestamp includes milliseconds:
Notice how both DateTime strings are the same? DateTime converted to string drops any millisecond data, but keep it as a DateTime object and you can run
unix_timestamp = Time.now.to_i
# => 1453667949
DateTime.strptime(unix_timestamp.to_s, "%s").to_s
# => "2016-01-24T20:39:09+00:00"
Let’s say your unix timestamp includes milliseconds:
unix_timestamp = (Time.now.to_f * 1000).to_i
# => 1453667949151
DateTime.strptime(unix_timestamp.to_s, "%Q").to_s
# => "2016-01-24T20:39:09+00:00"
DateTime.strptime
will allow you convert just about any formatted time string, see the docs for examples.Notice how both DateTime strings are the same? DateTime converted to string drops any millisecond data, but keep it as a DateTime object and you can run
strftime
and display it in any format you like:
DateTime.strptime(unix_timestamp.to_s, "%Q").strftime('%D %T:%L')
# => "01/24/16 20:39:09:151"
Monday, February 1, 2016
Don't wrap specific CSS elements
Another quickie quickie CSS tricky:
Let’s say you’re trying to make a site responsive to many different screen sizes, like you have to these days. You have a block of text that needs to wrap, but you also have a word or number you don’t want to get wrapped. The best example for this I can think of is a phone number – you don’t want it display weird like this:
Wrap that word or number or whatever in a
Let’s say you’re trying to make a site responsive to many different screen sizes, like you have to these days. You have a block of text that needs to wrap, but you also have a word or number you don’t want to get wrapped. The best example for this I can think of is a phone number – you don’t want it display weird like this:
Call Jenny today! 800-867-
5309
Wrap that word or number or whatever in a
span
and style it with "white-space: nowrap;"
. Then, that particular element will wrap as one piece: Call Jenny today!
800-867-5309
Monday, January 25, 2016
Arbitrary SQL ordering
I ran across an issue the other day where I had 4 records from the database that were being displayed in order of creation date, but I wanted them displayed in an arbitrary order - not alphabetical by name or title, or chronological, or sorted by id.
Before, I probably would have used Ruby to loop through the records and build an array by comparing ids. Now, though, I know better than to use Ruby for this type of thing, because it’s faster and better for memory to do it in SQL if possible (which I learned the hard way).
Turns out, querying using SQL looks a lot like what I would have written in Ruby anyhow:
Pretty cool! Thanks to cpjolicoeur on Github for this one.
Before, I probably would have used Ruby to loop through the records and build an array by comparing ids. Now, though, I know better than to use Ruby for this type of thing, because it’s faster and better for memory to do it in SQL if possible (which I learned the hard way).
Turns out, querying using SQL looks a lot like what I would have written in Ruby anyhow:
SELECT * FROM foo ORDER BY
CASE
WHEN id=67 THEN 1
WHEN id=23 THEN 2
WHEN id=1362 THEN 3
WHEN id=24 THEN 4
END
Pretty cool! Thanks to cpjolicoeur on Github for this one.
Monday, January 18, 2016
Migrating data in Rails using Rails migrations
Put this one in the “should’ve been obvious” column…
For an embarassingly long while, when I had a feature ready for deploy that required production data be modified for a whole bunch of records – for example, downcasing all
Not only is this bad code since it doesn’t keep a record of what happened, it’s also tedious because it’s an extra step that must be taken by whoever deploys the code.
Luckily there’s a better way - just put the updating login in a migration!
Example:
This example isn’t great because 1. there’s almost certainly a way to do this with pure SQL without instantiating every user record, and 2. it’s not reversible. But since I’m lazy and since it illustrates the point of the post, I’m leaving it.
For an embarassingly long while, when I had a feature ready for deploy that required production data be modified for a whole bunch of records – for example, downcasing all
name
attributes – I would write a one-off rake task to update those records, then delete that task.Not only is this bad code since it doesn’t keep a record of what happened, it’s also tedious because it’s an extra step that must be taken by whoever deploys the code.
Luckily there’s a better way - just put the updating login in a migration!
Example:
class DowncaseName < ActiveRecord::Migration
def up
User.where.not(name: nil).find_each do |user|
user.update!(name: user.name.downcase)
end
end
end
This example isn’t great because 1. there’s almost certainly a way to do this with pure SQL without instantiating every user record, and 2. it’s not reversible. But since I’m lazy and since it illustrates the point of the post, I’m leaving it.
Monday, January 11, 2016
No return value in rails console
A quick tip when working in rails console. If you're testing commands to run and don't want the console to output the return value, just append a semicolon to your ruby code.
OK, so that's a contrived example, but this really comes in handy
User.all
# => [#<user:0x007fd72a408630> {:id => 1, :name => "Mr. T", ...}, tons and tons of other records]
User.all;
# => nothing!
OK, so that's a contrived example, but this really comes in handy
- when creating records, or
- if you need to update several records in one shot and don't want to see the return values, or
- POSTing to an external API and avoiding all the cruft that comes in the response
Subscribe to:
Posts (Atom)