Recently I have an issues with some derived from ActiveRecord::Base class. I couldn’t get how the request was made through the chain of the method calls so I made a little hack to show the name of the method once it gets invoked.
So here’s the code:
https://gist.github.com/2828416
You could either include it in some kind of init.rb/environment.rb file to load it every time you run your project or you could enter it manually in the irb session.
Here’s the my example of usage (inside of irb): https://gist.github.com/2828602
NB: You could apply this technique not just to ActiveRecord::Base but also to all modules/classes you want (e.g. complicated classes derived from ActiveRecord::Base).
Filed under ruby activerecord tip
By default for :delete method in #link_to helper function:
<%= link_to “Delete User”, admin_user_path(@user.id), :method => :delete, :class => “btn danger” %>
Rails generates following HTML:
<a href=”/admin/users/3” class=”btn danger” data-method=”delete” rel=”nofollow“>Delete User</a>
All’s good but when you’ll start testing this code with Cucumber/Capybara you may notice errors, i.e. sending DELETE request as regular GET (as it’s written in href attribute).
So this step will not work:
Then /^I click on “Delete User” link for “([^”]*)” user$/ do |user_name|
click_link user_name
end
To achieve desired behavior you need to implicitly invoke #delete method, so the previous step should be rewritten as follows:
Then /^I click on “Delete User” link for “([^”]*)” user$/ do |user_name|
user = User.find_by_name(user_name)
user.should be
Capybara.current_session.driver.delete admin_user_path(user.id)
end
P.S.: You may also want to check whether the link has data-method attribute set to ‘delete’ before sending delete request.
Filed under cucumber BDD tip ruby capybara
The reason why the simple step definition with only one command could throw an error:
And I click on the “Add Client” link # features/step_definitions/create_client_by_admin_steps.rb:26
You have a nil object when you didn’t expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.[] (NoMethodError)
(eval):2:in `click_link’
./features/step_definitions/create_client_by_admin_steps.rb:31:in `/^I click on the “([^”]*)” link$/’
features/create_client_by_admin.feature:10:in `And I click on the “Add Client” link’
is that you didn’t specified “href” attribute in <a> tag or specified it wrong:
<a href=”javascript:void(0)” class=”btn danger” data-controls-modal=”add_client_modal_dialog”>Add Client</a>
while the right way to specify “href” attribute is this:
<a href=”#” class=”btn danger” data-controls-modal=”add_client_modal_dialog”>Add Client</a>
Filed under tip BDD cucumber capybara
If you want to test your integration with Authorize.net you could do it with a Visa test credit card number. The payment gateway has been designed so that this special test credit card number can be used to generate specific response codes or errors from Authorize.Net so that you may test your working code.
To cause the payment gateway to respond with a specific response code, send a transaction with the Visa error test credit card number (x_card_num) 4222222222222 and an amount (x_amount) equal to the response code you want the payment gateway to return.
For example, if a transaction is sent in Test Mode with the credit card number 4222222222222 and an amount of 12 dollars, the payment gateway will respond with response code 12, “Authorization Code is required but is not present.”
This could be very helpful in unit/functional tests (not only in Rails)
Source: Authorize.net documentation
Filed under authorize.net tip TDD
I’ve been using delayed_job for a while now and I must say it’s pretty unstable, plus it eats a lot of memory (especially in ruby 1.8). In order to add monitoring of dj daemon (e.g. restart it if it’s memory use is greater then some threshold) I tried monit and god utilities.
Monit (for whatever reason) could not execute inline bash script in “start” clause to enter application folder (which should be current folder to properly load rails environment and maybe some files from ./lib folder). So the only tool that works for me is god with config file as shown below.
Here’s simple god config for one delayed_job (could be easily scaled to multiple processes):
# run with: god -c /path/to/config.god [add -D if you want to not-deamonize god]
# This is the actual config file used to keep the delayed_job running
APPLICATION_ROOT = “/var/www/application”
RAILS_ENV = “production”
God.watch do |w|
w.name = “delayed_job_production”
w.interval = 15.seconds
w.start = “/bin/bash -c ‘cd #{APPLICATION_ROOT}/current; /usr/bin/env RAILS_ENV=#{RAILS_ENV} #{APPLICATION_ROOT}/current/script/delayed_job start > /tmp/delay_job.out’”
w.stop = “/bin/bash -c ‘cd #{APPLICATION_ROOT}/current; /usr/bin/env RAILS_ENV=#{RAILS_ENV} #{APPLICATION_ROOT}/current/script/delayed_job stop’”
w.log = “#{APPLICATION_ROOT}/shared/log/god_delayed_job.log”
w.start_grace = 30.seconds
w.restart_grace = 30.seconds
w.pid_file = “#{APPLICATION_ROOT}/shared/pids/delayed_job.pid”
w.behavior(:clean_pid_file)
w.start_if do |start|
start.condition(:process_running) do |c|
c.interval = 5.seconds
c.running = false
end
end
w.restart_if do |restart|
restart.condition(:memory_usage) do |c|
c.above = 300.megabytes
c.times = [3, 5] # 3 out of 5 intervals
end
restart.condition(:cpu_usage) do |c|
c.above = 50.percent
c.times = 5
end
end
# lifecycle
w.lifecycle do |on|
on.condition(:flapping) do |c|
c.to_state = [:start, :restart]
c.times = 5
c.within = 5.minute
c.transition = :unmonitored
c.retry_in = 10.minutes
c.retry_times = 5
c.retry_within = 2.hours
end
end
end
The same code in gist - https://gist.github.com/1237902
The key line here is:
w.start = “/bin/bash -c ‘cd #{APPLICATION_ROOT}/current; /usr/bin/env RAILS_ENV=#{RAILS_ENV} #{APPLICATION_ROOT}/current/script/delayed_job start > /tmp/delay_job.out’”
it starts delayed_job within correct environment (all as inline bash script to ensure ‘start’ is the one command) and with logging errors while starting to /tmp/delay_job.out.
You could store your config.god file in shared folder (if capistrano folder layout is used) and start god from command line like this:
god -c config.god
Then monitoring of all processes could be done with:
god status
The god gem lacks only convenient web-interface to check running processes (which monit have).
Resources:
God - a process monitoring framework in ruby
DelayedJob
Filed under god delayed_job gem ruby rails
I finally released redis_orm 0.6 gem. In this version:
- added equality operator for object, #to_s method for inspecting objects, #find! which could throw RecordNotFound error
- added self.descendants class method which returns all inherited from RedisOrm::Base classes
- introduced :sortable option (in property declaration and #find conditions hash) - rudimentary ability to sort records by any property (not just by default ‘created_at’)
- now handling models withing modules definitions (test for this in associations_test.rb)
- properly handling :as parameter in options for :has_many/:belongs_to self-references
- binding related models while creating model instance (like this: Article.create(:comment => comment))
- bunch of small fixes, updated tests and README.md
Source code: https://github.com/german/redis_orm
Gem: http://rubygems.org/gems/redis_orm
Filed under ruby gem redis redis_orm
If url you want to receive via HTTParty or Net::HTTP contains special characters (like ‘|’ or vowels with umlauts) an exception will be thrown:
» URI.parse “http://staticmaps.cloudmade.com/#{CLOUDMADE_API_KEY}/staticmap?size=600x500&styleid=4&bbox=51.5159,-0.0868016,51.5047,-0.0807667&marker=label:0|51.5159,-0.0807667&marker=51.5047,-0.0868016”
=> URI::InvalidURIError: bad URI(is not URI?):
To make URI.parse work you should invoke URI.encode on the url string first:
» URI.parse(URI.encode(“http://staticmaps.cloudmade.com/#{CLOUDMADE_API_KEY}/staticmap?size=600x500&styleid=4&bbox=51.5159,-0.0868016,51.5047,-0.0807667&marker=label:0|51.5159,-0.0807667&marker=51.5047,-0.0868016”))
=> #<URI::HTTP:0x7f0b095136d0 URL:http://staticmaps.cloudmade.com/#{CLOUDMADE_API_KEY}/staticmap?size=600x500&styleid=4&bbox=51.5159,-0.0868016,51.5047,-0.0807667&marker=label:0%7C51.5159,-0.0807667&marker=51.5047,-0.0868016>
Filed under gem tip
If you recently migrated from the well known SQL-land to the terra incognita of key-value storages (in particular to Redis) and are now wondering how the hell you’ll be handling all those avatars and photos users keep uploading to the servers, this small article is for you.
Things are much easier in case you are already using paperclip. Here are 3 steps you should follow to manage your file attachments with redis and paperclip:
1. Add “redis_orm” gem to your Gemfile:
gem “redis_orm”, “~> 0.5”
2. Inherit your model with attachments from RedisOrm::Base class like this:
class User < RedisOrm::Base
# here goes 4 specific to paperclip properties:
property :avatar_file_name, String
property :avatar_content_type, String
property :avatar_file_size, Integer
property :avatar_updated_at, Time
include Paperclip::Glue # here’s the most tricky part (:
has_attached_file :avatar, :styles => {:big => “900x900>”, :medium => “200x200>”, :chat => “42x42>”}
end
3. my pull request to paperclip has been recently merged (w00t!), so before new gem is released you should pull it right from github:
gem “paperclip”, :git => ‘git://github.com/thoughtbot/paperclip.git’
And that’s it! It just works.
All other code (e.g. on view and controller level) is specific to paperclip and could be found on their github page.
Filed under Redis paperclip tip redis_orm
I recently wrote an ORM for Redis key-value store. It tries to mimic ActiveRecord 2.x API.
It supports associations (belongs_to/has_many/has_one, self-referencing, polymorphic), ActiveModel’s validations, create/destroy/change callbacks, indices (in order to find records but not to increase the access speed) and dynamic finders.
Here’s an example of defining a model:
class User < RedisOrm::Base
property :first_name, String
property :last_name, String
timestamps
# OR
# property :created_at, Time
# property :modified_at, Time
index :last_name
index [:first_name, :last_name]
has_many :photos
has_one :profile
after_create :create_mailboxes
def create_mailboxes
# ...
end
end
More documentation could be found on https://github.com/german/redis_orm
Gem is available too https://rubygems.org/gems/redis_orm
Filed under gem ruby redis
Filed under tip github