Apr 03
I18n label is still not supported in rails 2.3.2. Here is the patch to make it work. However, I don’t want to change the source code of rails. Hence, I create a monkey patch.
module ActionView
module Helpers
class InstanceTag
def to_label_tag_with_i18n(text = nil, options = {})
text ||= object.class.human_attribute_name(method_name) if object.class.respond_to?(:human_attribute_name)
to_label_tag_without_i18n(text, options)
end
alias_method_chain :to_label_tag, :i18n
end
end
end
Load the file in the environment.rb or any file in confit/initializers will make it work.
Feb 11
ORDER BY items must appear in the select list if SELECT DISTINCT is specified.
Add the following code at the end of method add_limit_offset!(sql, options) in sqlserver_adapter.rb
if options[:order]
order_fields = options[:order].split(',').collect do |field|
column_name = field.split(" ")[0]
"#{column_name} AS #{column_name.gsub('.', '_')}"
end
sql.gsub!(/^\s*SELECT(\s+DISTINCT)(.*?) FROM/i, "SELECT\\1 \\2, #{order_fields.join(', ')} FROM")
end
Feb 06
In rspec, I usually need to define a matcher to match arguments. I don’t want to create a match for every should_receive method. I just want to assert the arguments I care. I try to define a code block to assert my call arguments. I google it for a while and could not find an answer.
I want to do something like:
User.should_receive(:find).with(assert_that(lambda { |args
options = args.pop
options[:include].should == expected_include
options[:limit].should == 100
}).and_return(:users)
After reading rspec source code, I finger out rspec should_receive argument allow code block. That’s easier than what I expect. The finial code is:
User.should_receive(:find).with do |*args|
options = args.pop
options[:include].should == expected_include
options[:limit].should == 100
true
end.and_return(:users)
remember to return true at the end if all assertions pass.
Jan 17
The current will_paginate plugin doesn’t support localization. Adding the following code into the application_helper will enable i18n for will_paginate.
include WillPaginate::ViewHelpers
def will_paginate_with_i18n(collection, options = {})
will_paginate_without_i18n(collection, options.merge(:previous_label => I18n.t(:previous), :next_label => I18n.t(:next)))
end
alias_method_chain :will_paginate, :i18n
And add ‘next’ and ‘previous’ attribute in the locales file.
for example zh.yml under RAILS_ROOT/config/locales
zh:
previous: '前一页'
next: '下一页'
Dec 30
SEO has become a hot topic in the Internet. I am working in my personal project which I’d like to have a friendly URL. I need to create a slug as my friend URL. But, the slug is case sensitive in my case. for example, word ‘fisher’ is different to name ‘Fisher’ in a dictionary. unfortunately, MySQL is case sensitive by default. So I need to change the setting for the slug field in my table.
I change my slug field in MySQL by adding the following code into my migration script:
execute %{ALTER TABLE TABLE_NAME MODIFY slug varchar(255) COLLATE utf8_bin NOT NULL}
That works fine in my production database which is MySQL. However, I am using sqlite3 in test which is case sensitive by default. So I need to modify the field only in MySQL database. The finial code I put in my migration script is following:
if ActiveRecord::Base.configurations[RAILS_ENV]['adapter'] == 'mysql'
execute %{ALTER TABLE words MODIFY slug varchar(255) COLLATE utf8_bin NOT NULL}
end
COLLATE options in MySQL:
- utf8_bin: compare strings by the binary value of each character
- utf8_general_ci: compare strings using general language rules, case insensitive
- utf8_general_cs: compare strings using general language case sensitive