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

Instance Method V.S. Singleton Method

Just keep in mind that methods written inside a class, for the benefit of all of that class’s instances, are instance methods, whereas a method defined for a specific object (def ticket.event) is a singleton method of that object.)

Nothing stops you from defining a method twice, or overriding it:
class C
      def m
            puts "First definition of method m"
      end
      def m
            puts "Second definition of method m"
      end
end
What happens when we call m on an instance of C? Let’s find out:
C.new.m
The printed result is Second definition of method m.

Most Ruby programmers are conservative. You’ll see less adding of methods to individual objects than you might expect. Methods are most often added to Class objects; those methods are class methods, which are a good design fit in many cases.

Organizing objects with class

我觉得“organize objects with class”这个命题特别好。它说明白了class是一种组织工具或者组织方式而已,而不是核心的东西——核心的、基础的东西是object。

David A. Black先生说过:Defining a class lets you group behaviors (methods) into convenient bundles, so that you can quickly create many objects that behave essentially the same way. 这就说明class存在的意义是:按照某种目的把behaviors打包。
比方说:地上胡乱堆放了一堆铁钉、螺丝、图钉、胶带、创可贴、胶水。妈妈叫你把这些东西分类归置好。你会怎么分类?我会把铁钉、螺丝、图钉挑出来放一个盒子里,贴上一个标签“铁钻物”;把胶带、创可贴、胶水放到另一个盒子里,标作“粘合品”。这就是“分类”——在英语里面叫class。为啥要这样分啊?因为铁钉、螺丝、图钉有类似的行为——在英语里叫behavior,在程序里我们通常叫method。

Classes are object factories. Classes are also special objects: They’re the only kind of object that has the power to spawn new objects (instances). Nonetheless, they are objects.

Local Variable

Local variables are variables that hold their value only during the execution of a particular section of code. They’re called local precisely because once program execution leaves the scope where the variable was created, the variable’s name no longer has any meaning.

Local variables give you a kind of scratch-pad facility. You can use, say, the variable name x in more than one place; as long as those places have different scopes, the two x variables are treated as completely separate.

Local variables can come into being in either of two ways:
■ Through assignment: x = object
■ As an entry in the method’s argument list, initialized when the method iscalled

Variables in Ruby don’t hold object values, rather, it contains a reference to an object.

Local variables have the quality of barewords; they must start with either a lowercase letter or the underscore character (_), and they must consist entirely of letters, numbers, and underscores.
我给自己制定的命名规则是:Local variable一律用“_”开头。例如:_one_apple

Here’s how Ruby decides what it’s seeing when it encounters a bareword:
1. If there’s an equal sign (=) to the right of the bareword, it’s a local variable undergoing an assignment.
2. If the bareword is a keyword, it’s a keyword.
3. Otherwise, the bareword is assumed to be a method call.

irb helps you what?

要开始使用irb,在Windows Command Prompt中只需输入irb,回车便进入irb环境。
比如要列出一个object都具有什么methods,可以这样:
$ irb
irb(main):001:0> puts Object.new.methods.sort

Every object in Ruby has a Boolean value defaultly

It’s a good idea to get used to the fact that everything in Ruby has a Boolean value, and sometimes it’s not what you may expect.
The Boolean value of almost every object in Ruby is true. The only objects whose Boolean value is false are the objects false and the special non-entity object nil.

Wednesday, March 14, 2007

Shortening the code via string interpolation

The string interpolation operator gives you a way to drop variables, method return values, or anything else, into a string. This can save you a lot of back-and-forth between print and puts:
puts "This ticket is for: #{ticket.event}, at #{ticket.venue}."
puts "The perform is #{ticket.performer}."
puts "The seat is #{ticket.seat}, "
puts "and it costs $#{"%.2f." % ticket.price}"
Whatever’s inside the interpolation operator #{...} gets calculated separately, and the results of the calculation are pasted automatically into the string.
When you run these lines, you don’t see the #{...} operator on your screen; instead, you see the results of calculating or evaluating what was inside that operator.

Rails Method without parentheses

The parentheses of a method are optional in most cases.
In cases where the syntax is more complex or you call more than one method in a row, you may need the parentheses to make it clear to Ruby what you mean. Most people use parentheses for method calls, but you’ll see method calls with no parentheses in most Rails applications.

dd

Sunday, March 11, 2007

Finanly, I come back to Ruby on Rails

一年前的这个时候,我正在家里痛并快乐着——没钱吃饭饿得肚子疼,但是在极其快乐地写Ruby on Rails程序。后来没办法,找了份软件咨询工作——在世界上最伟大的软件公司之一。因为要花很多时间学习公司的各种技术,所以非常痛苦地逼迫自己放下了Ruby on Rails,眼睁睁地看着别人愉快地play。中间自己也常常忍不住浏览关于Ruby on Rails的博客,写一些webapp,但是常被工作压没了时间。快一年过去了,公司的技术掌握地够用了,终于能有时间再回到Ruby on Rails了,由衷地感到愉快。

总感觉Ruby on Rails不仅仅是一种技术,也不仅是一种工作风格,更是一种生活风格。Ruby on Rails的哲学非常agile,其marketing做的更好。每次看到Ruby on Rails相关的文字、图片、声音、录影,总感觉很被吸引,即便还没有掌握它。这种感觉只有我老婆Cheng和Apple Inc.能给我!;-)

Tell method from field/variable throught English semantic

我从前还想过:Rails的method如果不写(),而只写成belongs_to,怎么与一些variable(比如customer_one)区分呢?现在我想明白了,主要是通过英语语义(semantic)啊!——动词、名词不是很容易就区分开了吗?动词基本就是method,名词就是variable一类的东西了。至少我们可以作为一个编程规范来遵循。

我觉得,写得好的Rails程序,应该就像是读一篇叙事短文(essay)一样,很自然(natural),很顺畅,很易懂。写这样的Rails程序,难道不就是在写作吗?这就是一种Life Style。我希望的生活就是每周有几天坐在Starbucks里,在MacBook Pro 17上这样“写作”。I love Ruby on Rails! and on Mac, because Mac is also a kind of life style.

Implementing predefined callback methods

Rails predefines quite a few callback and filter - methods like before_create, anticipating that you may want to perform programming actions in your application but not dictating what those actions should be. These filters are analogous to the helper-file facility: They’re a halfway measure that makes it easy for you to add the finishing touches.
Rails预先定义了很多Method Hook,当你把这个hook放到一个model class里面的时候,Rails就会执行这个hook。至于执行什么事情,决定于你在这个Method Hook里面填写上了什么东西。比如:
It might be more graceful to have a default string value for the description field. If no description exists for the edition at the time the database record is first created, let’s have it default to “standard”.
To bring this about, insert the following method definition into edition.rb (just prior to the end that ends the file):
def before_create
self.description = "standard" unless description
end
This code basically says: if description is nil, set it to “standard”.
The code is executed just before a new edition is saved to the database. Thus any edition without a description gets one.

Helper of Rails

A helper file, located in app/helpers, is created automatically for every controller you create.

Inside the helper files, you can write arbitrarily many Ruby methods; these methods are automatically accessible in your view template code. The advantage of this arrangement is that it saves you repetition, it's more encapsulated.
If you’re using a construct several times in one or more of your templates, you can write a method that generates the construct, and then call the method from the template.

Helper methods figure in Rails in two distinct related ways:
1, Rails provides you with the apps/helpers directory and file bank to encourage you to write methods that encapsulate functionality and to keep the view templates organized.
2, Rails also supplies you a large number of predefined helper methods. link_to is a perfect example: It’s a built-in Rails helper method that gives you a API to the creation of the HTML you need.
When you write helper methods, you’re adding to the stockpile of such methods that Rails has already given you.

Structured Freedom provided by Rails

You’re in charge of naming and writing the methods, but Rails provides an infrastructure that rationalizes and pre-systematizes the code for you.

An example of “structured freedom” are the method hooks available to you in your model definition files. A method hook is a method that you may, but aren’t obliged to, write; and if you do write it, it’s automatically called at a predefined point during program execution.
For example, if you write a method called before_create in one of your model files, then that method will be called automatically every time a database record corresponding to an instance of that model is created. This allows you to gatekeep the data in an orderly fashion and to manage your database at a low level while still writing everything in Ruby.

YAML used in Rails

YAML provides you with a way to store Ruby objects, including nested data structures, as text strings—and to thaw those strings back into life as Ruby objects.

Use the command to converts YAML string to Ruby object, and then prints out a representation of that object (with p):
$ ruby -ryaml -e 'p YAML.load(File.read("database.yml"))'
Rails is storing its configuration data as potential Ruby data, easily brought to life with a YAML operation.

Rails uses YAML in several contexts, such as database.yml.

Saturday, March 10, 2007

The frequent use of symbol objects as method arguments or hash keys

Discussions of Rails coding style always come back to the frequent use of symbol objects (such as :editions) as method arguments and/or hash keys in Rails applications.

In many cases, symbols serves usually with longer argument lists:
<%= link_to "A hyperlink in a view template",:controller => "main",:action => "welcome" %>
In this example, each symbol is associated with a value: the symbol :controller with the string “main”, the symbol :action with the string “welcome”. (The two symbols are hash keys, and the two strings are the corresponding hash values. The entire hash is the second argument to the method; the first argument is the first string: “A hyperlink in a view template”.) This syntax is standard Ruby.

It’s worth noting that the tendency of Rails developers to adhere to certain stylistic conventions becomes more important as the code gets more complex.

Seeing Rails as a domain-specific language PART3: in terminology

The consensus about syntax(与其它语言语法的同感) keeps the scenery uniform and familiar, while the semantics of the method, data, and file names give the landscape its specific character. Rails coding practice is so uniform.

Seeing Rails as a domain-specific language PART2: in syntax

A common Rails idiom we’ve already seen, and that you may have seen before, is this: has_many :editions
The syntax used here, with a verb-based directive on the left and what looks like a configuration spec on the right, seems like it could have been created specifically for a system like the Rails framework.
In fact, it’s a simple Ruby method call. The name of the method is has_many, and the argument is a Ruby symbol object. Every time anyone uses this method, it will look essentially the same.

You’ll almost certainly never see this send("has_many", "editions".intern) which is equivalent to the previous example (send is a do-it-yourself way to send a message to an object; intern converts a string object to a symbol object).
This send-based version is, admittedly, far-fetched enough not to be a close call. But you’ll probably never even see this much more slight variation on the original: has_many(:editions).
Many Ruby programmers like to put parentheses around method arguments, even when the parentheses are optional. But when writing Rails applications, even these programmers don’t use the parentheses—not because of Ruby (Ruby doesn’t care), but because leaving the parentheses off is a standard Rails convention.

The common idioms you use in Rails aren’t alternatives to Ruby; they’re alternatives within Ruby.
Long before Rails came along, it was possible to call a method with a symbol argument: method_from_ten_years_ago :symbol. And when Rails did come along, it—that is, its creator, core developers, and developer community—settled on this style of calling such a method. Ruby, mean while, is happy; this method-call style is a mainstream, idiomatic Ruby technique.

Part of learning Ruby as a Rails practitioner is recognizing what’s going on in your code, and the first lesson is that what’s happening is always Ruby. If you see thousands of has_many :editions and never see send("has_many", "editions".intern) or even has_many(:editions), it’s not because Rails has special syntax or rules, but because the Rails community has had the sense to rally around some coding conventions, gaining visual uniformity and a de facto language specificity for Rails development.

Seeing Rails as a domain-specific language PART1: in definition

A DSL is a language designed to be used for a specific task or set of tasks in a particular field or domain, rather than for general-purpose programming.

Rails is likewise a DSL written in Ruby. It’s true that Rails applications span a wide range of use and usefulness; and looking at the whole spectrum of Rails applications, from shopping sites to bulletin boards to bug-trackers, there may not seem to be anything specific about the Rails domain. But that’s just a reflection of the wide range of Web sites. Looking at it from the programming angle, Rails does have a specific domain: Web applications, particularly interactive, database-driven Web applications. ——我Rails就做这个做到极致,其它的都不管。所以,认为Rails是DSL是合适的。

It’s important to develop a sense of how the specificity of Rails is engineered and how it relates to Ruby. Rails, especially to someone who hasn’t seen much Ruby code outside of Rails, exhibits specificity at two levels: in the syntax, and in the terminology.

See Rails MVC from data

The controller is protected from having to deal directly with the database. So are you. When you write Rails application code, you always write code that manipulates data through nicely named, neatly ordered variables. The code you write triggers a cascade of database operations. But you don’t have to address the database directly.

You have to design the database, and you have to know what the database tables and fields are called (because that knowledge has a direct bearing on what your model can do). But then you manipulate the database at an abstract level.

On the one hand, the controller has access to the universe of the models, through which it can manipulate data; and on the other hand, it has the ability to share data with the view template.

Friday, March 09, 2007

The lifecycle of a Rails run

The process of listening to and responding to a request coming in to a Rails application can be broken into several stages:

  1. the Web server talking to the dispatcher (which is a Ruby program);
  2. the dispatcher awakening the appropriate controller and asking that controller to perform aparticular action;
  3. the performance of that action;
  4. the filling out of the view, based on the data manipulations carried out in the controller action.

Error Mongrel : Erron::EBADF

我今晚遇到了一次这样的错误:[Mongrel] Errno::EBADF (Bad file descriptor)

发现仅仅是因为我的MySQL服务根本没启动,哈哈哈!启动了,就好了。

Error Rails : LoadError in Controller


[ERROR #001]

这个错误解决了。错误产生原因是sort_by语法写错了。

Check the log file

CHECKING THE DEVELOPMENT LOG FILE If something did not go well, and if you can’t tell what’s wrong, just look in the log/development.log file. Hereyou’ll see error messages that tell you about syntax and other errors that may have been encountered.

Specifying a default top-level-page with a route

We need to define a route: a translation rule, which is applied to the URL of the incoming request to a Rails application. Routes are defined in the file config/routes.rb.

In this case, we want to translate an empty URL into a call to the welcome action of the main controller. Add the following line, which must be the first map.connect line in the file:
map.connect '', :controller => "main", :action => "welcome"
This line establishes the rule that will perform the appropriate translation of anempty URL.

注意:To get this default page working correctly, you also have to remove the default default page public/index.html. A best practice is rename it to index.html.hidden, so that it won’t compete for top-level-page status with the main/welcome action.

Courtesy of ActiveRecord

Courtesy的意思是:周到殷勤的举动。ActiveRecord的确是太殷勤了,就像一个英国管家,把各种打猎器具都准备好了,主人想干什么了,管家就会选好器具递到眼前。

In the edition/show.rhtml template, notice that a number of method calls to the object @edition—and double-barreled method calls, like @edition.work.title—are used to extract the information necessary to complete the view.

Again, none of these methods had to be defined manually. Some of them exist as a result of directives in the model file—specifically, the directive belongs_to :work in the file edition.rb.
ActiveRecord model files containing association directives (belongs_to, has_many) will prompt Rails to engineer the relationships among entities that you need.

Some, such as year and price, exist because the editions table in the database has fields with those names.

The methods spring into being, courtesy of ActiveRecord, so that you can pass information back and forth between the database records and your program using simple Ruby method-call syntax.

ActiveRecord models are the Ruby incarnation(化身) of the same domain universe that governs your database design.

First, design a Basic Layout

PROCESS
当开始design views工作时,我们首先设计一个default layout,我个人更倾向于使用
Basic Layout。这个"基础版面"包含了我们在每个view上都需要显示的元素。然后,我们再开始设计每一个单独的view。

Basic Layouts are like meta-templates. They contain general template code that surrounds the specific template code of one or more views. Basic Layout generall contains all kinds of site-wide elements that it would be a nuisance to have to insert individually into every template file.
A typical basic layout might include a header bar, a menu bar, a copyright notice, etc.
The basic layout also contains appropriate XML declarations—again, saving you the trouble of putting them in every template file.

HOW-TO-USE basic layout?
The layout uses a “magic” variable @content_for_layout at the point where you want the specific view inserted.

创建一个文件application.rhtml,放到app/views/layouts 目录下,这就成了整个webapp的default layout。Rails默认application.rhtml为“全站默认版面”。COOL ! Convention over Configuration

Thoughts of Ruby on Rails Workshop

应该不仅仅教授Ruby和Rails的最常用知识和技巧,还应该教授一套自己的develop pickups——就是从针对每一类问题的众多解决方法中挑选出一种,作为自己的selected pattern,并一般不在使用其它解决方法。从而达到对一种方法越用越熟,熟而生巧的效果。

Basics of Veiw

A View is an ERb program that shares data with Controllers through mutually accessible Variables. 首先,view是一个ERb程序。然后,View同Controller共享数据(通过Variable)。

Controller actions and View template files are connected through naming conventions:
An incoming request for the picture/display Action triggers execution of the display method in the picture Controller, followed by rendering of the picture/display.rhtml file in the Views area.

Basicly, the Controller prepares the data and stores it in Variables, and those Variables are used in the ERb file corresponding to that Action.

Modeling Associations of database tables

Model:You need to add directives that tell Rails about the associationsbetween entities—that is, the details of the has and belongs_to relationships.Associations are part of the ActiveRecord database-handling library. They’re a kind of inter-entity modeling subsystem, in which you tell Rails what you consider the relationships between entities to be and, assuming the table and field names you’ve chosen mesh with what you’ve asserted, Rails responds by handing you a set of programming features that let you manipulate those relationships easily.

Ruby Variables

The composer controller stashes a particular composer into a variable called @composer. The values contained in these variables are available to the ERb code in the respective views.

About Action

Action:The purpose of an action is to stuff data into Ruby variables that the ERb code in the view file canunstuff and display. So, we need to anticipate what data the view will need.

Both the work show action and the edition show action will utilize a common Rails idiom: grabbing the value of the CGI variable id and using it as an index to find the correct instance of the relevant entity. In other words, if you’re in the work controller, performing the show action, and the value of the CGI variable id is 2, then you want to show the work that’s indexed as 2. Exactly what indexed means(how the number translates into which work is produced) is up to the model. But in the typical case, 2 will be treated as the value of the id field in the appropriate database table.

Thursday, March 08, 2007

Ruby symbol

Reference:
Understanding Ruby Symbols

13 Ways of Looking at a Ruby Symbol

Creating Controller with actions

The process for creating a controller is always the same:
$ ruby script/generate controller contollername actionname
This command accomplishes several tasks:
■ It creates a file named app/controllers/controllername_controller.rb.
■ It inserts an empty method definition for the actionname action into that file.
■ It creates a file called app/views/controllername/actionname.rhtml, which will be the file in which you place the ERb template code for this view.

或者先只创建controller以后再创建action:
$ ruby script/generate controller controllername

The majority of controllers correspond directly to an entity model: If there’s a“work” controller, then there’s probably a “work” model.

Wednesday, March 07, 2007

MySQL Tips

在Windows Command Prompt中

1,登陆MySQL:
$ mysql -u username -p
$ Enter password: ******

2,显示所有数据库:
myslq> show databases;

3,打开数据库:
myslq> use databasename;

4,显示数据库databasename中所有的表:
myslq> use databasename;
myslq> show tables;

5,显示数据库表tablename的信息:
myslq> describe tablename;

Basic Mongrel operation

在Win32上安装Mongrel:
$ gem install win32-service (pick the most recent one)
$ gem install mongrel (pick the win32 pre-built)
$ gem install mongrel_service (Great to run Mongrel as a Windows service)

使用Mongrel运行一个application:
$ cd myrailsapp
$ mongrel_rails start

停止Mongrel运行:
$ mongrel_rails stop
在Windows Command下,用ctrl+c结束。

Modeling the domain in database and Rails

第一步,Diagraming the domain:
1,先把domain都列出来,包括属性。
2,然后用一个个的方块表示出来,就像UML那样,但是不要那么复杂。而且不要用工具来做这件事情,就用铅笔在纸上画出来。

第二步,Initializing the databases:
1,使用root用户创建为该应用创建一个专门的用户,比如dillone。
2,创建一个schema,命名和application的名字一样,只不过字母都小写,比如comeback。
3,赋予dillone对于comeback的读写等权限。
4,使用dillone登陆MySQL,在comeback下创建三个库comeback_development, comeback_production, and comeback_test。遵循Ruby on Rails的命名规范。

第三步,Designing and creating the database tables:
1,创建一个create_tables.sql文件,把要创建的数据库表都用SQL写好。
2,创建一个insert_data.sql文件,把要注入的数据都准备这里,写好SQL语句。
3,创建一个drop_tables.sql文件,用来清除数据库表。
我把这三个文件SQL文件作为“标配”放在每个Rails app的db目录下。
注意:严格写Rails-friendly SQL:

  • Each entity gets a table in the database named after it, but in the plural.
  • Each such entity-matching table has a field called id, which contains aunique integer for each record inserted into the table.
  • Given entity x and entity y, if entity y belongs to entity x, then table y has a field called x_id.
  • The bulk of the fields in any table store the values for that entity’s simple properties (anything that’s a number or a string).
  • 数据库表名全部用小写,字段名全部小写,多词的名字中间用_连接,字段类型也用全部小写,例如:tagsiddescriptionpicturesvarchardatetimeopinion_idfk_op_picture
  • SQL语句中的关键字用全部大写,例如:CONSTRAINTPRIMARY KEYFOREIGN KEYCREATENOT NULLREFERENCESDROP

第四步,Composing the config/database.yml file:
development:
adapter: mysql
database: comeback_development
username: root
password:
host: localhost

test:
...

production:
...
注意:在使用rails appname命令创建一个新应用的时候,appname最好都是小写英文字母,不要首字母大写。这样在这个文件中生成的database: comeback_development 就会是小写的。如此,就与数据库名的大小写一致起来了。

第五步,Writing the Rails model files:
1,Rails creates models semi-automatically. From the top level of the application directory, issue the following commands:
$ ruby script/generate model work
$ ruby script/generate model edition
$ ruby script/generate model composer
You’ll find the three files work.rb, edition.rb, composer.rb in the app/models directory. 这些文件中的内容看上去只是empty definitions of Ruby classes,但实际上they have facilities for setting and retrieving all the entity properties. Rails endows them with those facilities automatically。
2,You need to add directives that tell Rails about the associations between entities—the details of the has and belongs_to relationships.

Tuesday, March 06, 2007

Practice Ruby before playing with Rails

去年我最开始学习和使用Rails的时候,经常会很苦恼程序不知道该怎么写,或者看不懂一些语法,比如@game,:picture,::Record。对学习Rails很有打击。后来才意识到,这根本不是Rails本身不好用,而是因为我不了解Ruby语言。我建议在开始学习和使用Rails之前或者初期多练习使用Ruby语言,这样会事半功倍。特别是要了解那些Ruby的“特殊符号”。

续写...
这几天在读Ruby for Rails--Ruby techniques for Rails developers这本书,是David A. Black著作的,David Heinemeier Hansson写了前言。这是一本非常好的书,结构清晰、目的明确、语言平实。我觉得比Programming Ruby更适合因为要使用Rails而学习Ruby语言的人。
在前言中,David Heinemeier Hansson也表达了和我同样的认识:

To fully realize the potential of Rails, it’s crucial that you take the time
tofully understand Ruby—and with Ruby for Rails David has provided just what
youneed to help you achieve that goal.

我向Rails developer推荐这本书Ruby for Rails

Setup Rails development environment on Windows

Go to http://www.rubyonrails.org/down.

1, Download and install Ruby. (Ruby Interpreter)
2, Download and setup RubyGems. (The standard Ruby package manager) Then you can use RubyGems to install Rails, Mongrel from Internet.