Tag: rails
Memos on “Advanced YAML Fixtures” of RoR
by broom9 on Oct.08, 2008, under myPoorTech
YAML Fixtures in Rails 2.0 have some pretty cool features. One of them is “auto generated primary IDs”, and another cooler one is “Label references for associations (belongs_to, has_one, has_many)”. You can find explanations and examples of them in the link above. But there is a pitfall to notice: the second feature actually depends on the first one. In other words, “Label references for associations” may not work if you’re not applying auto generated IDs in your fixture.
The method behind the scene of auto generated IDs feature is Fixture#identify, which is simply a hash process on the label of the fixture row. When the fixture loader handles the label references, it will call the Fixture#identify method directly to get the ID of associated models. So here is a typical failure case.
### in pirates.yml
reginald:
id: 1
name: Reginald the Pirate
monkey: george
### in monkeys.yml
george:
name: George the Monkey
pirate: reginald # the fixture loader will use the result of Fixture.identify('reginald') here! not "1".
Using hashed label as auto generated ID is a pretty smart idea. It avoids the troubles to find fixture references between each other and the pain of detecting fixture reference loop. There is a plugin named “Fixture Reference” which actually solves the problem in this tedious way. But I prefer the Rails 2.0 way because it looks more elegant and smarter.
However, sometimes we still need to include primary IDs in the fixtures, for some constants like country/state/city/timezone. Sometimes it’s easier to export them from the database as CSV, since fixture loader can handle CSV files. In this case, refer them in other fixtures by ID, not by label. Or to be safer, don’t give these fixtures label at all.
So the best practice and maybe the “correct” way to use Rails 2.0 fixture is : Specify either ID or label , don’t mix them in a single fixture file.
A Pitfall of skip_before_filter
by broom9 on Aug.30, 2008, under myPoorTech
In rails, a common task is to use skip_before_filter to skip a certain global before_filter on several actions.
For example
skip_before_filter :authenticate, :only => [:login]
But if somehow we did calls in this format twice
skip_before_filter :authenticate, :only => [:login]
skip_before_filter :authenticate, :only => [:index]
Then only the latest one will work, the action “login” will be filtered by “authenticate” again, in the example above.
This is a little bit reasonable, because you might mean the latest set when you specify “only” repeatedly. But it WAS a pitfall I fell into. Maybe an option like “:overwrite” on the “before_filter” will be more friendly to user.
Before_filter Order in Rails
by broom9 on May.28, 2008, under myPoorTech
A typical way to add before filter to controllers in Rails is use the codes like this in controllers
class ApplicationController < ActionController::Base before_filter :login_required ... end
And if we declare more than one before filter, they are put into an array and form a filter chain. “filter_chain” is a class inheritable attribute of controller class, so you could use this line in Rails console to check what filters are working for a certain controller.
c: \> ruby script\console
>> puts Services::AdvertiserController.filter_chain.
>> map(&:filter).join("\n")
login_required
......
authorize
=> nil
>>
But sometimes plugins and other codes will try to add before_filter in a tricky way.
ActionController::Base.send :before_filter, :authorize
When the 2 declaration ways of before_filter mix together, it’s easy to be confused the order of before filters… For example, the “login_required” filter should work before “authorize” (check permissions of a user). But if I enable authorize before_filter in a “init.rb” file of a plugin, it will probably work before “login_required”.
And if you add a before_filter twice, it will appear in the filter chain twice. If you want to make sure a filter runs after another, a dirty trick is
skip_before_filter :login_required, :authorize before_filter :login_required, :authorize
But this will make ppl confused even faster.
By the way, the plugin load order in Rails 1.2.x is not reliable either. Here is an intro about it, and Rails 2.0 has improved this feature.
So, my conclusion about before_filter, a best practice, is to avoid enabling before_filter in plugins or lib files, just provide the before_filter and let the app developers decide when and in what order to enable it.
The magical “self” when doing Mixin in Ruby
by broom9 on Apr.15, 2008, under myPoorTech
Here is a sample code snippet, which will show my problem. I put this file in the script directory of a Rails project to run.
$:.unshift(File.dirname(__FILE__) + "/../vendor/rails/activesupport/lib")
require 'active_support'
class App
end
module M
def self.included(base)
base.class_eval do
class_inheritable_accessor :h
end
base.extend ClassMethods
end
module ClassMethods
def not_work
h = 1
end
def work
self.h = 2
end
end
end
App.send(:include, M)
puts App.h
App.not_work
puts App.h
App.work
puts App.h
You could see that the “self” keyword made a difference when calling the reader method of a class_inheritable_reader. This looks really weird until I checked the implementation of class_inheritable_reader.
def class_inheritable_reader(*syms)
syms.each do |sym|
next if sym.is_a?(Hash)
class_eval <<-EOS
def self.#{sym}
read_inheritable_attribute(:#{sym})
end
def #{sym}
self.class.#{sym}
end
EOS
end
end
How to View Rails Log "Colorfully" in Windows
by broom9 on Nov.11, 2007, under myPoorTech
I was learning Ruby on Rails recently and it’s pretty impressive that Rails has done almost every annoying settings and configurations for you….ok, this post isn’t about saying good words for RoR. I want to show my tiny survey on “how to view the Rails log file in Windows”.
As default, Rails produces a very nice log file under the directory “%project_home%/log”, recording detail information of every request, such as path, parameters, session data, SQLs… They are nicely indented and colored by some ascii color controlling characters (I don’t know the exact name of these characters… anyone who knows that please tell me, thank you), but the console in Windows doesn’t support that. So the log will appear like below in windows console.
The “tail” command here is from GNUWin32 CoreUtils.
Apparently this is far from nice…
After tried some tools, including UltraEdit, RadRails (console window), Tail for Win32. I surprisingly found a small tool AsciiArtViewer (author’s homepage, download link) can display these color controlling stuff correctly… But this tool can’t work like the tail command (updating realtimely), so I continued my search.
Finally I got a good tool – MinGW-msys. Actually it’s a Minimal SYStem, based on MinGW and offering a Bourne Shell environment. It has the built-in “tail” command and displays color controlling characters correctly. The download page is here, and what you should look for is “MSYS Base System“. I’m using MSYS-1.0.10.exe.
The color theme of msys console can be configured by editing the file “c:\msys\1.0\msys.bat”.
————
Some co-worker told me in RadRails it’s also possible to get a pretty format. Right click the log file in resource navigator and choose “Tail” :)
————
Another update, Install Cygwin and add the “bin” directory of cygwin to system path, then everything will be fine….It’s a shame not to realize this earlier =_=






