How could it be that my database.yml disappears?
Probably was in the repository once and got deleted in a commit that you pulled.
Plotting graphs in Ruby with Gruff
Geoffrey Grosenbach has created Gruff for easily plotting graphs. It is written in pure Ruby and integrates with Rails applications.
It provides features as automatic sizing of dots and lines (the more values, the thinner the graph's elements), custom or predefined themes, different styles (bar, line, dot and many more) and multiple graphs in one chart.
Installation
In your Gemfile:
gem 'rmagick', :require => false
gem 'gruff'
Then run bundle install
(and don't forget to restart your development server.)
Usage
This i...
The Ruby Toolbox – a collection of good gems
If you need a gem for a certain purpose, be sure to check this site.
The rankings are determined by counting up the number of forks and watchers of various github projects, so I'd view it less as "this is what I should be using," and more as "these are some things I should check out." At the very least, they're all likely to be under active development and fairly up to date, and it's very useful to see groups of gems broken down by category.
Guide to localizing a Rails application
Localizing a non-trivial application can be a huge undertaking. This card will give you an overview over the many components that are affected.
When you are asked to give an estimate for the effort involved, go through the list below and check which points are covered by your requirements. Work with a developer who has done a full-app localization before and assign an hour estimate to each of these points.
Static text
- Static strings and template text in
app
must be translated: Screens, mailer templates, PDF templates, helpe...
MySQL 5.1: Switch to InnoDB Plugin for better performance
MySQL version 5.1 comes with an alternative, faster InnoDB implementation (called "InnoDB Plugin").
Switching is easy:
- Stop your mysqld with
sudo stop mysql
- Add the following lines to your
/etc/mysql/my.cnf
under the[mysqld]
section
ignore-builtin-innodb
plugin-load=innodb=ha_innodb_plugin.so - Start your mysqld with
sudo start mysql
The file format has not changed, your tables should survive this.
Note: This is not necessary in MySQL 5.5, where the new implementation is the default.
How to use pessimistic row locks with ActiveRecord
When requests arrive at the application servers simultaneously, weird things can happen. Sometimes, this can also happen if a user double-clicks on a button, for example.
This often leads to problems, as two object instances are modified in parallel maybe by different code and one of the requests writes the results to the database.
In case you want to make sure that only one of the requests "wins", i.e. one of the requests is fully executed and completed while the other one at least has to wait for the first request to be completed, you ha...
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 ...
salesking/king_dtaus
DTAUS & DTAZV are formats for German bank transfers and is short for "Datenträgeraustausch". The format itself totally sucks because it was established in the last century, to be used on floppy disks. Still almost all German banks use it (they only seem innovative at robbing), and it is therefore supported in common banking programs too.
This gem saves you all the trouble when generating DTAUS- or DTAZV-text.
Why has_many :through associations can return the same record multiple times
An association defined with has_many :through
will return the same record multiple times if multiple join models for the same record exist (a n:m relation). To prevent this, you need to add ->{ uniq }
as second argument to has_many
(below Rails 4 it is a simple option: has_many :xyz, :uniq => true
).
Example
Say you have an Invoice
with multiple Items
. Each Item
has a Product
:
class Invoice < ActiveRecord::Base
has_many :items
has_many :products, :through => :items
end
class Item < ActiveRecord::Base
...
Validate attachment presence using paperclip
Make sure you call the methods in the following order and not vice versa:
has_attached_file :image
validates_attachment_presence :image
Validation with condition works fine, too:
validates_attachment_presence :image, :if => :method
This is because validates_attachment_presence
is only available after saying has_attached_file
.
Shell script to deploy changes to production and not shoot yourself in the foot
Geordi, our collection of command line tools, has been extended by another command deploy-to-production
. This script encapsulates the following workflow:
- Pull the production branch.
- Show which commits from the master would make it to production with this deploy.
- Ask if you want to proceed.
- If yes, merge the master into the production branch, push and deploy with
bundle exec cap production deploy:migrations
The script will ask you for the names of your master branch, production branch an...
validates_acceptance_of is skipped when the attribute is nil
validates_acceptance_of :terms
only works if terms
is set to a value. The validation is skipped silently when terms
is nil
.
While this behavior is useful to validate acceptance in the frontend and not the admin backend, it also makes it very easy to unintentionally skip the validation altogether by forgetting to add the checkbox to a form. E.g. validates_acceptance_of :terms_with_typo
will be skipped silently even if there is no column with t...
Change how Capybara sees or ignores hidden elements
Short version
- Capybara has a global option (
Capybara.ignore_hidden_elements
) that determines whether Capybara sees or ignores hidden elements. - Prefer not to change this global option, and use the
:visible
option when callingpage.find(...)
. This way the behavior is only changed for this onefind
and your step doesn't have confusing side effects. - Every Capybara driver has its own notion of "visibility".
Long version
Capybara has an option (Capybara.ignore_hidden_elements
) to configure the default...
Customize path for Capybara "show me the page" files
When you regularly make use of Cucumber's "show me the page" step (or let pages pop up as errors occur), the capybara-20120326132013.html
files will clutter up your Rails root directory.
To tell Capybara where it should save those files instead, put this into features/support/env.rb
:
Capybara.save_and_open_page_path = 'tmp/capybara'
Connecting the "sequel" gem to MSSQL via ODBC
After you configured your ODBC describe in
- Fix [RubyODBC]Cannot allocate SQLHENV when connecting to MSSQL 2005 with Ruby 1.8.7. on Ubuntu 10.10
- and Connecting to MSSQL with Ruby on Ubuntu - lambie.org
you can connect with sequel
:
require "rubygems"
require "se...
Fix [RubyODBC]Cannot allocate SQLHENV when connecting to MSSQL 2005 with Ruby 1.8.7. on Ubuntu 10.10
I followed this nice guide Connecting to MSSQL with Ruby on Ubuntu - lambie.org until I ran in the following errors:
irb(main):001:0> require "dbi"; dbh = DBI.connect('dbi:ODBC:MyLegacyServer', 'my_name', 'my_password')
DBI::DatabaseError: INTERN (0) [RubyODBC]Cannot allocate SQLHENV
from /usr/lib/ruby/1.8/dbd/odbc/driver.rb:36:in `connect'
from /usr/lib/ruby/1.8/dbi/handles/driver.rb:33:in `connect'
from /usr/lib/ruby...
ActiveRecord: Overwriting a setter causes trouble with attributes depending on each other
Undeterministically I got a nil
error on saving the object caused by the random order of hash elements of the params hash.
class Feedback
belongs_to :user
def role=(value)
@role = value
self.email = find_email_by_name(user.name)
end
end
This piece of code works well until the object params hash contains a second element when it is updated like this:
@feedback.update_attributes!(params[:feedback])
Now it is no longer ensured that user
was set before name
was set. If the name...
Creating the inverse of a Rails migration
Let's say you need to revert a migration that happened a while back. You'd create a new migration that removes what was added back then in the up
path, while its down
path restores the old functionality.
While you could just copy&paste the down
and up
parts of it to the inverse part of the new migration, you may not want to do that. Especially when the up/down paths already contained some logic (that executed update
statements on the created column, for example), copying does not feel right.
Someone already added the logic how to...
Gatekeeping: Guide for developer
If your project manager wants to do gatekeeping on a project, as a developer you need to follow the following guidelines (e.g. by using something like this issue checklist template).
In order to reduce the number of rejects we get from clients, we want to review all code written before it goes to the staging server.
Note
This process is tailored to our specific needs and tools at makandra. While it will certainly not apply to all (especially larger teams), we think it...
TeamViewer 7 finally works with multiple screens under Linux
TeamViewer 6 and lower had an issue where they would see a multi-monitor Linux setup as a single wall of pixels. This is fixed in version 7. The guest can now select the currently active screen from the TeamViewer menu.
ActiveRecord: When aggregating nested children, always exclude children marked for destruction
When your model is using a callback like before_save
or before_validation
to calculate an aggregated value from its children, it needs to skip those children that are #marked_for_destruction?
. Otherwise you will include children that have been ticked for deletion in a nested form.
Wrong way
class Invoice < ApplicationRecord
has_many :invoice_items
accepts_nested_attributes_for :invoice_items, :allow_destroy => true # the critical code 1/2
before_save :calculate_and_store_amount # the crit...
will_paginate on complex scopes may be slow (workaround)
will_paginate
triggers a database query to determine the total number of entries (i.e. to let you display the number of search results). When you paginate complex scope (e.g. that has many include
s), this query may take several seconds to complete.
If you encounter this behavior, a solution is to calculate the total count yourself and pass it to the pagination call:
scope = User.complex_scope_full_of_includes
total_number_of_users = scope.count
@users = scope.paginate(:total_entr...
In MySQL, a zero number equals any string
In MySQL comparing zero to a string 0 = "any string"
is always true!
So when you want to compare a string with a value of an integer column, you have to cast your integer value into a string like follows:
SELECT * from posts WHERE CAST(posts.comments_count AS CHAR) = '200'
Of course this is usually not what you want to use for selecting your data as this might cause some expensive database operations. No indexes can be used and a full table scan will always be triggered.
If possible, cast the compared value in your application to...