Wednesday, April 18, 2007

Rake fixture

在修改完migration后,如果要把development数据库中的结构复制到test数据库中,使用以下命令:
$ rake db:test:clone_structure

sdfs

Rake Migration

在修改完webapp/db/migrate下的rb文件内容后——修改数据库表结构,运行以下命令执行到数据库表中:
$ rake db:migrate

但是我需要先把数据库中的表全部drop掉,然后才能执行这个命令。否则执行了也没有任何效果。在开发webapp的过程中,经常会需要修改数据库表——修改migration文件,有没有更更简便的方法来再次执行migrate的动作?

我要求自己ONLY使用Migration来创建和修改数据库表结构,坚决不再使用SQL语句创建。

Reference:
http://api.rubyonrails.com/classes/ActiveRecord/Migration.html

Tuesday, March 20, 2007

Hashes in Rails method calls

With a knowledge of hashes as well as symbols, you’re now in a position to understand
this construct:
<%= link_to "Click here",:controller => "work",:action => "show",:id => work.id %>
This is the classic Rails method-call look and feel.
This is a method call with two arguments: the string “Click here” and a three-key hash.

You might expect to see curly braces around the hash, like this:
link_to("Click here", { :controller => "work", :action => "show", :id => work.id })
But as a special sugar dispensation, Ruby permits you to end an argument list, when you call a method, with a literal hash without the curly braces.

Why does Ruby allow this special usage?
To facilitate and “prettify” precisely the kind of labeling of method arguments by descriptive name that’s so common in Rails.
Passing arguments as key/value pairs allows you to indicate what the arguments are for.
The elimination of the curly braces gives the idiom a clean look.

Monday, March 19, 2007

Collection, Container, in Ruby

In programming generally, you deal not only with individual objects but with collections of objects. 这就是为什么会有collection这个词汇的原因。:-)

Ruby represents collections of objects by putting them inside container objects. In Ruby, two built-in classes dominate the container-object landscape: Array and Hash.

A built-in Ruby module called Enumerable, which encapsulates a great deal of the functionality of arrays and hashes.

An array is an ordered collection of objects, ordered meaning that you can select objects from the collection based on a consistent numerical index.

Hashes are unordered collections, they store objects in pairs, each pair consisting of a key and a value. You retrieve a value by means of the key.

The Rails framework, too, makes heavy use of hashes. A large number of the most common methods used in writing Rails applications take hashes as their arguments.

Array

To create an Array: Rails 通常使用a = []这种方式,而不使用a = Array.new的方式。

To insert an element into the array, you do this:
a = []
a[0] = "something"

To add an object to the beginning of an array, you can use unshift:
a.unshift("something")

To add an object to the end of an array, you use push:
a = [1,2,3,4]
a.push(5)
a.putsh(6, 7, 8)

或者使用a << 5,不过这种方式一次只能加一个value。

Corresponding to unshift and push are their opposite numbers, shift and pop.

To add the contents of array b to array a, you can use concat:
$ [1,2,3].concat([4,5,6])
$ => [1, 2, 3, 4, 5, 6]

To combine two arrays into a third, new array, you can do so with the + method:
$ a = [1, 2, 3]
$ b = [4, 5, 6]
$ put c = a + b
$ => [1, 2, 3, 4, 5, 6]

To replace the contents of one array with the contents of another, use replace:
$ a = [1,2,3]
$ a.replace([4,5,6])

a.each

a.find

a.

Hash

To create a hash:
h = {}
for example:
state_hash = { "Connecticut" => "CT","Delaware" => "DE","New Jersey" => "NJ","Virginia" => "VA" }

The => operator connects a key onthe left with the value corresponding to it on the right.

To add a key/value pair to a hash, you use essentially the same technique as foradding an item to an array: the []= method :
state_hash["New York"] = "NY"

To iterate over a hash several ways. Like arrays, hashes have a basic each method. On each iteration, an entire key/value pair is yielded to the block, in the form of a two-element array:
$ h = {1 => "one", 2 => "two" }
$ h.each do key, value
      puts "The word for #{key} is #{value}."
end

dfd

Symbol in Ruby on Rails

Symbols are instances of the built-in Ruby class Symbol. They have a literal constructor: the leading colon.
:book, :"Here's how to make a symbol with spaces in it."
You can also create a symbol programmatically, by calling the to_sym method or intern method on a string, as irb shows:
$ "a".to_sym
$ :a

Indeed, symbols are very closely related strings. They share responsibility for representing units of text. However, strings and symbols differ in some important ways:
1, Every time you see the notation for a particularsymbol (:a), you’re seeing the same symbol object represented. If you see two identical-looking string literals"a""a" you’re seeing two different string objects.
2, Symbols,unlike strings, are immutable; you cannot add, remove, or change parts of a symbol. 就是说symbol是不可改变的,而string是可以改变内容的。

It’s worth knowing that symbols are efficient in terms of memory usage and processing time. Strings, on the other hand, come with an entourage of behaviors and capabilities that makes them more expensive to maintain and process (like being made longer than they started out, having their contents changed, and so on).

Using symbols in Rails

You’ll often see symbol literals used as arguments to methods and, especially, as hash keys. Hashes that serve as arguments to methods are a doubly likely candidate for symbol usage.

In the case of method calls in Rails applications, a consensus exists on the syntax of method calls whose arguments are symbols. Using symbol literals is second nature in Rails development.
<%= link_to "Click here", :controller => "book", :action => "show", :id => book.id %>
This is an example of a method argument hash: Each of the symbols is a key, and each of the values to the right is a value. This style of method call is common in Rails application code.

Sunday, March 18, 2007

Code block & keyword yield

Code block is a kind of construct, is an optional component of method call.

When you call a method—any method, any time, with or without arguments—you have the option of supplying a code block.

But why would you add a block of code to a method call? You’d do it so that your method can yield:
If you provide a code block when you call a method, then inside the method, you can yield control to that code block to execute the code in the block, and return control to the method body right after the call to yield.

Like a method, a code block can take arguments:
Methods do this with parenthetical lists of variable names for the arguments:
def one_method (a,b,c)
end
Code blocks have a different syntax; instead of parentheses, they use a pair of pipes (I I):
one_code_block do I a, b, c I
end

我觉得这yield没啥意思。如果需要半路这样的话,我调用另一个method不就行了。

Instance variables and self

One of the most useful and important rules to learn in Ruby is this:
Every instance variable you see in a Ruby program belongs to whatever object is the current object (self) at that point.

Thursday, March 15, 2007

Module

Like classes, modules are bundles of methods and constants.
Unlike classes, modules don’t have instances; instead, you specify that you want the functionality of a particular module to be added to the functionality of a class, or of a specific object.

It’s no accident that modules are similar in many respects to classes: The class Class is a subclass of Module. Judging by the family tree of classes, class is a specialized form of module.

We saw that Object is the highest class; here, we’ll meet the highest module: Kernel.

When you write a class, you then create instances of the class. Those instances can execute the class’s instance methods.
Modules, however, don’t have instances. Instead, modules get mixed in to classes.
When this happens, the instance of the class has the ability to call instance methods defined in the module.
Modules are sometimes referred to as mix-ins.

The mix-in operation is achieved with the include statement. include is actually a method.

The main difference between inheriting from a class and mixing in a module is that you can mix in more than one module.
No class can inherit from more than one class. In cases where you want numerous extra behaviors for a class’s instances—and you don’t want to stash them all into the class’s superclass—you can use modules to organize your code in a more granular way. Each module can add something different to the methods available through the class.

When to use Module?

Modules open up lots of possibilities, particularly for sharing code among more than one class , because any number of classes can mix in the same module.

The greatest strength of modules is that they help you with program design and flexibility.

Modules encourage modular design: program design that breaks large components into smaller ones and lets you mix and match object behaviors.

When you’re designing a program and you identify a behavior or set of behaviors that may be exhibited by more than one kind of entity or object, you’ve found a good candidate for a module.

Refer to Class Method and Class Constant from outside of the class definition

A class object (like Ticket) has its own methods, its own state, its own identity. It doesn’t share these things with instances of itself.
我们可以把Class Method看作是class自己的Singleton Method. Class是制造object的工厂,工厂当然可以有自己的method啊!这些method是不给object的。

In referring to Ruby methods outside of code, it’s customary:
1, to refer to instance methods by naming the class in which they are defined, followed by a hash mark (#), and the name of the method;
2, to refer to class methods with a similar construct but using a period (.).
Sometimes you’ll see a double colon (::) instead of a period in the class method case.
我要求自己严格遵循:
Instance Method of a class写成:Ticket#show_price
Class Method of a class写成:Ticket::show_most_expensive

Class Constant
We refer to the constant from outside the class definition using a special path notation: a double colon (::).
class Ticket
      VENUES = ["Convention Center", "Fairgrounds", "Town Hall"]
end
$ puts "We've closed the class definition."

$ puts "So we have to use the path notation to reach the constant."
$ puts "The venues are:"
$ puts Ticket::VENUES

The double-colon notation pinpoints the constant VENUES inside the class known by the constant Ticket, and the list of venues is printed out.

Attribute

In Ruby terminology, properties of objects that you can set and/or get are called attributes.
In the case of ticket objects, we would say that each ticket has a price attribute as well as a date attribute and a venue attribute.

Ruby has a shortcut lets us create that style of method: a method that reads and returns the value of the instance variable with the same name as the method. We do it like this:

class Ticket
      attr_reader :venue, :date
      attr_writer :studio
      attr_accessor :price
end

attr_reader是只读的attribute;
attr_writer是只写的attribute;
attr_accessor等于attr_readerattr_writer

Using Setter method to change object state dynamically

The Setter method are methods defined at the end with an equal sign (=).
def price=(amount)
      @price = amount
end

you can then call it just like any other method:
ticket.price=(65.00)
或者使用syntactic sugar方式:
ticket.price = 65.00

When the interpreter sees the message “price” followed by “ =”, it automatically ignores the space before equal sign and reads the single message “price=”—a call to the method whose name is price=, which we’ve defined.
As for the right-hand side: parentheses are optional on single arguments to methods, so you can just put 65.00 there and it will be picked up as the argument to the price= method.

Instance variables and object state

Information and data associated with a particular object is called the state of the object.
我们应该能够做到:set/reset and read the state of an object。


The instance variable enables individual objects to remember state. Instance variables work much like other variables: You assign values to them, and you read those values back.
However,instance variables have a few differences.
1, Instance variable names always start with @. This enables you to recognize an instance variable at a glance.
2, Instance variables are only visible to the object to which they belong.
3, An instance variable is initialized in one method definition, inside a particular class.

Instance这个词意味着什么呢?意味着class instance,也就是object。所以,instance variable是和class没有关系的,只和一个具体的object有关系。
根据上面的第三条描述,一个instance variable是在一个class的method中初始化的。所以 ,在定义一个class的时候,写在method里面的才是instance varialbe,才能够被每个instance所使用。
但是,一个class本身也是一个object,所以,在method之外的variable就是该class这个object本身自己的instance variable了,与这个class的instance们没有关系。

Unlike a local variable, the instance variable @ivar retains the value assigned to it even after the method in which it was initialized has terminated. This property of instance variables—their survival across method calls—makes them suitable for maintaining state in an object.

我们常常要把arguments赋给Instance Variable。我对自己的编程要求是: Instance Varialbe的名字必须与argument的名字一样,例如:@word = word