How belongs_to is constructed

Another jewelry found in "Ruby for Rails"

   1: module A
   2:   module M
   3:     module ClassMethods
   4:       def a_sort_of_class_method
   5:         puts "Instance method of ClassMethods module"
   6:         puts "So this can be made to act like a class method"
   7:         puts "(if a Class object calls it directly)"
   8:       end
   9:     end
  10:     def self.included(c)
  11:       c.extend(ClassMethods)
  12:     end
  13:   end
  14:   class B
  15:     include M
  16:   end
  17: end
  18:  
  19: class C < A::B
  20:   a_sort_of_class_method
  21: end

The author’s review on this design is also great:

If you find this convoluted, don’t feel discouraged. It is—but it’s convoluted
for the sake of clean organization. Instead of writing belongs_to and the other
association methods directly as class methods of ActiveRecord::Base, Rails puts
them in a module that clearly labels them with the role they’re going to play:
ActiveRecord::Associations::ClassMethods. Then, ActiveRecord::Base is extended
with that module, at which point things proceed as if that module’s
instance methods were class methods of ActiveRecord::Base the whole time. The
best of both worlds is preserved: The code remains organized and labeled with
meaningful class and module names, while the programmer can do things like:
class Edition < ActiveRecord::Base
belongs_to :publisher
# etc.
end
without having to worry about how ActiveRecord::Base ended up having a
method called belongs_to.


$:.unshift(File.dirname(__FILE__))

Looks weird? Yes to me. Luckily, I found a thorough explanation in "Ruby for Rails"

$:.unshift(File.dirname(__FILE__))

This line adds the directory containing active_record.rb to the loadpath of
require. It does this in the following way:

■ The variable $: holds the loadpath, which determines the search order
used by require.
■ __FILE__ is a special Ruby variable that holds the name of the current file:
active_record.rb.
■ File.dirname returns the directory part of the full path- and filename of the
file—in this case, /usr/local/lib/ruby/gems/1.8/gems/activerecord-
1.9.1/lib or equivalent.
■ The unshift operation adds that directory to the front of the load path.

NOTE THE POSITION OF THE CURRENT DIRECTORY IN THE RUBY LOADPATH
By default, the Ruby loadpath includes the current directory, indicated
by the single dot (.) at the end of the list of load directories. (You can see
them all if you do ruby -e ‘p $:’.) Also by default, the current directory
is whatever directory was current when the program started executing; so
if you’re in directory zero and give the command ruby one/two/
prog.rb, prog.rb will consider zero (not two) to be its runtime current
directory. This means that even if two files are in the same directory, you
can’t necessarily just require one from the other without either modifying
the loadpath ($:) or using a full pathname in the require statement.
The upshot of all this is that Rails does a fair amount of directory and
loadpath manipulation, so that the files that need to see each other can
indeed see each other.


Ruby FAQ of mine

This is the collection of various problems I met during my learning of Ruby. Hope it could also help you 🙂

 

 

symptom:

solution:

problem of installing json gem.

ERROR: Error installing json:
ERROR:Failed to build gem native extension.

gem install json_pure

E-textEditor

Can’t run ruby problem

remove RUBYOPT environment variable.

Install local gems

gem install –local filename.gem

Add gem source

gem sources -a <gem source>

Remove gem source

gem sources -r <gem source>

Install gems using specified server

gem install <gemName> -s <serverName>


Git Cheat Sheet

git-cheat-sheet-medium


Ruby sample: Randomly run a method from multiple alternatives

As we all know, there are different ways to do the same thing on Windows. For example, to save a document, we could either click File->save from menu or punch Ctrl-S on keyboard, I call them alternatives. I, as a QA, need to test alternatives. Ruby is once again show its powerful dynamic weapon, and its quite easy to accomplish this with the below code.

   1: class Object
   2:     def self.inherited(subclass)
   3:         if @subclasses
   4:             @subclasses << subclass
   5:         else
   6:             @subclasses = [subclass]
   7:         end
   8:     end
   9:  
  10:     def self.subclasses
  11:         @subclasses
  12:     end
  13: end
  14:  
  15: class Array
  16:    def random
  17:       self[rand(self.length)]
  18:    end
  19: end
  20:  
  21:  
  22: class    Talkable
  23:     def talk
  24:         raise "This is abstract method that must be implemented in the derived class"
  25:     end
  26:     def self.do_some_talk
  27:         talker = self.subclasses.random.new
  28:         talker.talk
  29:     end
  30: end
  31:  
  32: class Chinese < Talkable
  33:     def talk
  34:         puts "Ni hao"
  35:     end
  36: end
  37:  
  38: class American < Talkable
  39:     def talk
  40:         puts "Hi"
  41:     end
  42: end
  43:  
  44: class Geek < Talkable
  45:     def talk
  46:         puts "..."
  47:     end
  48: end
  49:  
  50: Talkable.do_some_talk

There are some interesting things happened in the above lines of code 🙂

1. Line#1-#13, As there is no build-in method for looking for all subclass. We need to invent it.

2. Line#15-#19, Similarly, define a random method to randomly pick up an item from Array.

3. Line#23-#25, An interface in ruby, don’t know it other do it this way, but it works 🙂


Solution for “can’t activate rubyforge (= 0.4.5), already activated rubyforge-1.0.0”

It confused me for days, and it’s more frustrated to find those answers with dummy descriptions. And finally, when I am almost plan to quit, I find this. Although in Japanese, it’s clear enough for me to understand these words:)

   1: gem uninstall rubyforge --version=1.0.0
   2: gem install rubyforge --version=0.4.5

Actually, I only need to run first command to run make rake db:migrate task. Anyone know Japanese, translate this for me 🙂

redmineを動かそうと script/server したらタイトルのようなエラーが。Googleで探せどもいまいちしっくりくる解決策がありません。

そもそも、rubyforge-1.0.0を必要としてるのは何か、と調べてみたら、hoeの1.5.3でした。hoeの1.5.1までは rubyforge 0.4.5を使っていて、hoeの1.5.3は1.0.0を使っているとのこと。で、ZenTestのようにhoeに依存しているものは、1.5.1以上であればいい模様。ということで、

gem install rubyforge –version=0.4.5

gem uninstall hoe –version=1.5.3

gem uninstall rubyforge –version=1.0.0

として解決しました。


转:Winddows下架设轻巧的RoR环境

原文

Windows + e texteditor + cgywin + console2
a) 安装e texteditor
url: http://www.e-texteditor.com/download/e_beta_setup.exe
安装
注意安装途中可能报错,那是个别文件不符合windows命名规则的原因,不用管,ignore掉然后继续就好了,影响不大。
b) 安装cgywin
初次运行e texteditor就会提示安装cgywin,直接选automatic install就好了,e texteditor会自动下载cgywin
c) 安装console2
下载console2
url: http://sourceforge.net/projects/console/
解压即可
配置console和cgywin
选add tab, 在shell里面输入:
c:cygwinbinbash –login –i
将该tab移到最上方,以后每次启动console2都会自动启动该shell
d) 安装RubyGem
Download RubyGem code
url: http://rubyforge.org/frs/?group_id=126
Untar
tar –xzvf rubygems-1.1.0.tgz
Setup
Sudo ruby setup.rb
验证安装
gem –v
which gem
如果出现错误,使用:
unset RUBYOPT

e) 安装rails
安装
sudo gem update –system
sudo gem install rails –include-dependencies
验证安装
rails -v

f) 测试安装
rails blog
cd blog
e .
你将会看到e texteditor 自动启动并将当前目录的项目打开。