﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-wash-随笔分类-ruby rails</title><link>http://www.blogjava.net/wash/category/10948.html</link><description /><language>zh-cn</language><lastBuildDate>Sun, 18 Mar 2007 05:54:18 GMT</lastBuildDate><pubDate>Sun, 18 Mar 2007 05:54:18 GMT</pubDate><ttl>60</ttl><item><title>programming ruby 2nd--extending ruby 1</title><link>http://www.blogjava.net/wash/archive/2006/06/15/52995.html</link><dc:creator>wash</dc:creator><author>wash</author><pubDate>Thu, 15 Jun 2006 06:53:00 GMT</pubDate><guid>http://www.blogjava.net/wash/archive/2006/06/15/52995.html</guid><wfw:comment>http://www.blogjava.net/wash/comments/52995.html</wfw:comment><comments>http://www.blogjava.net/wash/archive/2006/06/15/52995.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wash/comments/commentRss/52995.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wash/services/trackbacks/52995.html</trackback:ping><description><![CDATA[1.Ruby Object  in c <br />2.juke box extension <br />3.memory allocation<br />4.ruby type system<br />5.create an exception<br />6embed a ruby interpreter<br />7.bridge to other language<br />8.c api<br />1.<br />p269<br />Sometimes, though, life is more complicated. Perhaps you want to define a global variable<br />whose valuemust be calculated when it is accessed. You do this by defining hooked<br />and virtual variables. A hooked variable is a real variable that is initialized by a named<br />function when the corresponding Ruby variable is accessed. Virtual variables are similar<br />but are never stored: their value purely comes from evaluating the hook function.<br />See the API section that begins on page 294 for details.<br />If you create a Ruby object from C and store it in a C global variable without exporting<br />it to Ruby, you must at least tell the garbage collector about it, lest ye be reaped<br />inadvertently.<br />static VALUE obj;<br />// ...<br />obj = rb_ary_new();<br />rb_global_variable(obj);<img src ="http://www.blogjava.net/wash/aggbug/52995.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wash/" target="_blank">wash</a> 2006-06-15 14:53 <a href="http://www.blogjava.net/wash/archive/2006/06/15/52995.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> Primary Keys and IDs</title><link>http://www.blogjava.net/wash/archive/2006/05/11/45625.html</link><dc:creator>wash</dc:creator><author>wash</author><pubDate>Thu, 11 May 2006 03:41:00 GMT</pubDate><guid>http://www.blogjava.net/wash/archive/2006/05/11/45625.html</guid><wfw:comment>http://www.blogjava.net/wash/comments/45625.html</wfw:comment><comments>http://www.blogjava.net/wash/archive/2006/05/11/45625.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wash/comments/commentRss/45625.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wash/services/trackbacks/45625.html</trackback:ping><description><![CDATA[You may have noticed that our sample database tables all define an integer<br />column called id as their primary key. This is an Active Record convention.<br />“But wait!” you cry. “Shouldn’t the primary key of my orders table be the<br />order number or some other meaningful column? Why use an artificial<br />primary key such as id?”<br />The reason is largely a practical one—the format of external data may<br />change over time. For example, you might think that the ISBN of a book<br />would make a good primary key in a table of books. After all, ISBNs are<br />Report erratum Prepared exclusively for Don Francis<br />PRIMARY KEYS AND IDS 198<br />unique. But as this particular book is being written, the publishing industry<br />in the US is gearing up for a major change as additional digits are<br />added to all ISBNs.<br />If we’d used the ISBN as the primary key in a table of books, we’d have to<br />go through and update each row to reflect this change. But then we’d have<br />another problem. There’ll be other tables in the database that reference<br />rows in the books table via the primary key. We can’t change the key in the<br />books table unless we first go through and update all of these references.<br />And that will involve dropping foreign key constraints, updating tables,<br />updating the books table, and finally reestablishing the constraints. All in<br />all, something of a pain.<br />If we use our own internal value as a primary key, things work out a lot<br />better. No third party can come along and arbitrarily tell us to change<br />things—we control our own keyspace. And if something such as the ISBN<br />does need to change, it can change without affecting any of the existing<br />relationships in the database. In effect, we’ve decoupled the knitting<br />together of rows from the external representation of data in those rows.<br />Now there’s nothing to say that we can’t expose the id value to our end<br />users. In the orders table, we could externally call it an order id and print<br />it on all the paperwork. But be careful doing this—at any time some regulator<br />may come along and mandate that order ids must follow an externally<br />imposed format, and you’d be back where you started.<br />If you’re creating a new schema for a Rails application, you’ll probably<br />want to go with the flow and give all of your tables an id column as their<br />primary key. If you need to work with an existing schema, Active Record<br />gives you a simple way of overriding the default name of the primary key<br />for a table.<br />class BadBook &lt; ActiveRecord::Base<br />set_primary_key "isbn"<br />end<br />Normally, Active Record takes care of creating new primary key values<br />for records that you create and add to the database—they’ll be ascending<br />integers (possibly with some gaps in the sequence). However, if you override<br />the primary key column’s name, you also take on the responsibility<br />of setting the primary key to a unique value before you save a new row.<br />Perhaps surprisingly, you still set an attribute called id to do this. As far as<br />As we’ll see later, join tables are not included in this advice—they should not have an id column.<br />Active Record is concerned, the primary key attribute is always set using<br />an attribute called id. The set_primary_key declaration sets the name of the<br />column to use in the table. In the following code, we use an attribute<br />called id even though the primary key in the database is isbn.<br />book = BadBook.new<br />book.id = "0-12345-6789"<br />book.title = "My Great American Novel"<br />book.save<br /># ...<br />book = BadBook.find("0-12345-6789")<br />puts book.title # =&gt; "My Great American Novel"<br />p book.attributes #=&gt; {"isbn" =&gt;"0-12345-6789",<br />"title"=&gt;"My Great American Novel"}<br />Just to make things more confusing, the attributes of the model object<br />have the column names isbn and title—id doesn’t appear. When you need<br />to set the primary key, use id. At all other times, use the actual column<br />name.<br /><img src ="http://www.blogjava.net/wash/aggbug/45625.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wash/" target="_blank">wash</a> 2006-05-11 11:41 <a href="http://www.blogjava.net/wash/archive/2006/05/11/45625.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Accessing Attributes</title><link>http://www.blogjava.net/wash/archive/2006/05/11/45618.html</link><dc:creator>wash</dc:creator><author>wash</author><pubDate>Thu, 11 May 2006 03:09:00 GMT</pubDate><guid>http://www.blogjava.net/wash/archive/2006/05/11/45618.html</guid><wfw:comment>http://www.blogjava.net/wash/comments/45618.html</wfw:comment><comments>http://www.blogjava.net/wash/archive/2006/05/11/45618.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wash/comments/commentRss/45618.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wash/services/trackbacks/45618.html</trackback:ping><description><![CDATA[If a model object has an attribute named balance, you can access the<br />attribute’s value using the indexing operator, passing it either a string or<br />a symbol. Here we’ll use symbols.<br />account[:balance] #=&gt; return current value<br />account[:balance] = 0.0 #=&gt; set value of balance<br />However, this is <font color="#ff3300">deprecated</font> in normal code, as it considerably reduces<br />your options should you want to change the underlying implementation<br />of the attribute in the future. Instead, you should access values or model<br />attributes using Ruby <font color="#ff3333">accessor methods.<br /></font>account.balance #=&gt; return current value<br />account.balance = 0.0 #=&gt; set value of balance<br />The value returned using these two techniques will be cast by Active<br />Record to an appropriate Ruby type if possible (so, for example, if the<br />database column is a timestamp, a Time object will be returned). If you<br />want to get the raw value of an attribute, append _before_type_cast to the<br />method form of its name, as shown in the following code.<br /><br />COLUMNS AND ATTRIBUTES 195<br />David Says. . .<br />Overriding Model Attributes<br />Here’s an example of the benefits of using accessors to get at the<br />attributes of models. Our account model will raise an exception immediately<br />when someone tries to set a balance below a minimum value.<br />class Account &lt; ActiveRecord::Base<br />def balance=(value)<br />raise BalanceTooLow if value &lt; MINIMUM_LEVEL<br />self[:balance] = value<br />end<br />end<br />account.balance_before_type_cast #=&gt; "123.4", a string<br />account.release_date_before_type_cast #=&gt; "20050301"<br />Finally, inside the code of the model itself, you can use the read_attribute( )<br />and write_attribute( ) private methods. These take the attribute name as a<br />string parameter.<br /><font color="#ff3333">Boolean Attributes</font><br />Some databases support a boolean column type, others don’t. This makes<br />it hard for Active Record to abstract booleans. For example, if the underlying<br />database has no boolean type, some developers use a char(1) column<br />containing “t” or “f” to represent true or false. Others use integer columns,<br />where 0 is false and 1 is true. Even if the database supports boolean types<br />directly (such as MySQL and its bool column type), they might just be<br />stored as 0 or 1 internally.<br />The problem is that in Ruby the number 0 and the string “f” are both<br />interpreted as true values in conditions.4 This means that if you use the<br />value of the column directly, your code will interpret the column as true<br />when you intended it to be false.<br /># DON'T DO THIS<br />user = Users.find_by_name("Dave")<br />if user.superuser<br />grant_privileges<br />end<br />4Ruby has a simple definition of truth. Any value that is not nil or the constant false is<br />true.<br /><br />To query a column in a condition, you must append a question mark to<br />the column’s name.<br /># INSTEAD, DO THIS<br />user = Users.find_by_name("Dave")<br />if user.superuser?<br />grant_privileges<br />end<br />This form of attribute accessor looks at the column’s value. It is interpreted<br />as false only if it is the number zero; one of the strings "0", "f", "false",<br />or "" (the empty string); a nil; or the constant false. Otherwise it is interpreted<br />as true.<br />If you work with legacy schemas or have databases in languages other than<br />English, the definition of truth in the previous paragraph may not hold.<br />In these cases, you can override the built-in definition of the predicate<br />methods. For example, in Dutch, the field might contain J or N (for Ja or<br />Nee). In this case, you could write<br />class User &lt; ActiveRecord::Base<br />def superuser?<br />self.superuser == 'J'<br />end<br /># . . .<br />end<br />Storing Structured Data<br />It is sometimes convenient to store attributes containing arbitrary Ruby<br />objects directly into database tables. One way that Active Record supports<br />this is by serializing the Ruby object into a string (in YAML format) and<br />storing that string in the database column corresponding to the attribute.<br />In the schema, this column must be defined as type text.<br />Because Active Record will normally map a character or text column to a<br />plain Ruby string, you need to tell Active Record to use serialization if you<br />want to take advantage of this functionality. For example, we might want<br />to record the last five purchases made by our customers. We’ll create a<br />table containing a text column to hold this information.<br />File 6 create table purchases (<br />id int not null auto_increment,<br />name varchar(100) not null,<br />last_five text,<br />primary key (id)<br />);<br />In the Active Record class that wraps this table, we’ll use the serialize( )<br />declaration to tell Active Record to marshal objects into and out of this<br />column.<br />File 8 class Purchase &lt; ActiveRecord::Base<br />serialize :last_five<br /># ...<br />end<br />When we create new Purchase objects, we can assign any Ruby object to<br />the last_five column. In this case, we set it to an array of strings.<br />File 8 purchase = Purchase.new<br />purchase.name = "Dave Thomas"<br />purchase.last_five = [ 'shoes', 'shirt', 'socks', 'ski mask', 'shorts' ]<br />purchase.save<br />When we later read it in, the attribute is set back to an array.<br />File 8 purchase = Purchase.find_by_name("Dave Thomas")<br />pp purchase.last_five<br />pp purchase.last_five[3]<br />This code outputs<br />["shoes", "shirt", "socks", "ski mask", "shorts"]<br />"ski mask"<br />Although powerful and convenient, this approach is problematic if you<br />ever need to be able to use the information in the serialized columns outside<br />a Ruby application. Unless that application understands the YAML<br />format, the column contents will be opaque to it. In particular, it will be<br />difficult to use the structure inside these columns in SQL queries. You<br />might instead want to consider using object aggregation, described in Section<br />15.2, Aggregation, on page 247, to achieve a similar effect.<img src ="http://www.blogjava.net/wash/aggbug/45618.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wash/" target="_blank">wash</a> 2006-05-11 11:09 <a href="http://www.blogjava.net/wash/archive/2006/05/11/45618.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Active Record Basics</title><link>http://www.blogjava.net/wash/archive/2006/05/10/45399.html</link><dc:creator>wash</dc:creator><author>wash</author><pubDate>Wed, 10 May 2006 03:12:00 GMT</pubDate><guid>http://www.blogjava.net/wash/archive/2006/05/10/45399.html</guid><wfw:comment>http://www.blogjava.net/wash/comments/45399.html</wfw:comment><comments>http://www.blogjava.net/wash/archive/2006/05/10/45399.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wash/comments/commentRss/45399.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wash/services/trackbacks/45399.html</trackback:ping><description><![CDATA[Active Record is the object-relational mapping (ORM) layer supplied with<br />Rails. In this chapter, we’ll look at the basics of Active Record—connecting<br />to databases, mapping tables, and manipulating data. We’ll dig deeper<br />into the more advanced stuff in the next chapter.<br />Active Record closely follows the standard ORM model: tables map to<br />classes, rows to objects, and columns to object attributes. It differs from<br />most other ORM libraries in the way it is configured. By using a sensible<br />set of defaults, Active Record minimizes the amount of configuration that<br />developers perform. To illustrate this, here’s a program that uses Active<br />Record to wrap a table of orders in a MySQL database. After finding the<br />order with a particular id, it modifies the purchaser’s name and saves the<br />result back in the database, updating the original row.<br /><br />require "rubygems"<br />require_gem "activerecord"<br />ActiveRecord::Base.establish_connection(:adapter =&gt; "mysql",<br />:host =&gt; "localhost", :database =&gt; "railsdb")<br />class Order &lt; ActiveRecord::Base<br />end<br />order = Order.find(123)<br />order.name = "Dave Thomas"<br />order.save<br /><br />That’s all there is to it—in this case no configuration information (apart<br />from the database connection stuff) is required. Somehow Active Record<br />figured out what we needed and got it right. Let’s have a look at how this<br />works.<br /><br />14.1 Tables and Classes<br />When you create a subclass of ActiveRecord::Base, you’re creating something<br />that wraps a database table. By default, Active Record assumes that<br />the name of the table is the plural form of the name of the class. If the class<br />name contains multiple capitalized words, the table name is assumed to<br />have underscores between these words. Some irregular plurals are handled.<br />Class Name<br />Order<br />TaxAgency<br />Diagnosis<br />Batch<br />Table Name<br />tax_agencies<br />orders<br />batches<br />diagnoses<br />LineItem<br />Person<br />Datum<br />Quantity<br />Class Name<br />line_items<br />people<br />quantities<br />data<br />Table Name<br />These rules reflect DHH’s philosophy that class names should be singular<br />while the names of tables should be plural. If you don’t like this behavior,<br />you can disable it by setting a global flag in your configuration (the file<br />environment.rb in the config directory).<br />ActiveRecord::Base.pluralize_table_names = false<br />The algorithm used to derive the plural form of a table name is fairly simplistic.<br />It works in the majority of common cases, but if you have a class<br />named Sheep, it’ll valiantly try to find a table named sheeps. The assumption<br />that the table name and class names are related might also break<br />down if you’re operating with a legacy schema,2 where the table names<br />might otherwise force you to use strange or undesirable class names in<br />your code. For this reason, Active Record allows you to override the default<br />generation of a table name using the set_table_name directive.<br /><br /><br />14.2 Columns and Attributes<br />Active Record objects correspond to rows in a database table. The objects<br />have attributes corresponding to the columns in the table. You probably<br />noticed that our definition of class Order didn’t mention any of the columns<br />in the orders table. That’s because Active Record determines them dynamically<br />at runtime. Active Record reflects on the schema inside the database<br />to configure the classes that wrap tables.3<br />Our orders table might have been created with the following SQL.<br />File 6 create table orders (<br />id int not null auto_increment,<br />name varchar(100) not null,<br />email varchar(255) not null,<br />address text not null,<br />pay_type char(10) not null,<br />shipped_at datetime null,<br />primary key (id)<br />);<img src ="http://www.blogjava.net/wash/aggbug/45399.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wash/" target="_blank">wash</a> 2006-05-10 11:12 <a href="http://www.blogjava.net/wash/archive/2006/05/10/45399.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> Logging in Rails and Debugging Hints and use breakpoint</title><link>http://www.blogjava.net/wash/archive/2006/05/10/45387.html</link><dc:creator>wash</dc:creator><author>wash</author><pubDate>Wed, 10 May 2006 02:51:00 GMT</pubDate><guid>http://www.blogjava.net/wash/archive/2006/05/10/45387.html</guid><wfw:comment>http://www.blogjava.net/wash/comments/45387.html</wfw:comment><comments>http://www.blogjava.net/wash/archive/2006/05/10/45387.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wash/comments/commentRss/45387.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wash/services/trackbacks/45387.html</trackback:ping><description><![CDATA[ Logging in Rails<br />Rails has logging built right into the framework. Or, to be more accurate,<br />Rails exposes a Logger object to all the code in a Rails application.<br />Logger is a simple logging framework that ships with recent versions of<br />Ruby. (You can get more information by typing ri Logger at a command<br />prompt or by looking in the standard library documentation in Programming<br />Ruby [TH01]). For our purposes, it’s enough to know that we can<br />generate log messages at the warning, info, error, and fatal levels. We can<br />then decide (probably in an environment file) which levels of logging to<br />write to the log files.<br />logger.warn("I don't think that's a good idea")<br />logger.info("Dave's trying to do something bad")<br />logger.error("Now he's gone and broken it")<br />logger.fatal("I give up")<br />In a Rails application, these messages are written to a file in the log directory.<br />The file used depends on the environment in which your application<br />is running. A development application will log to log/development.log, an<br />application under test to test.log, and a production app to production.log.<br /><br />13.7 Debugging Hints<br />Bugs happen. Even in Rails applications. This section has some hints on<br />tracking them down.<br />First and foremost, write tests! Rails makes it easy to write both unit<br />tests and functional tests (as we saw in Chapter 12, Task T: Testing, on<br />page 132). Use them, and you’ll find that your bug rate drops way down.<br />You’ll also decrease the likelihood of bugs suddenly appearing in code that<br />you wrote a month ago. Tests are cheap insurance.<br /><br />Tests tell you whether something works or not, and they help you isolate<br />the code that has a problem. Sometimes, though, the cause isn’t immediately<br />apparent.<br />If the problem is in a model, you might be able to track it down by running<br />the offending class outside the context of a web application. The<br />scripts/console script lets you bring up part of a Rails application in an irb<br />session, letting you experiment with methods. Here’s a session where we<br />use the console to update the price of a product.<br />depot&gt; ruby script/console<br />Loading development environment.<br />irb(main):001:0&gt; pr = Product.find(:first)<br />=&gt; #&lt;Product:0x248acd0 @attributes={"image_url"=&gt;"/images/sk..."<br />irb(main):002:0&gt; pr.price<br />=&gt; 29.95<br />irb(main):003:0&gt; pr.price = 34.95<br />=&gt; 34.95<br />irb(main):004:0&gt; pr.save<br />=&gt; true<br />Logging and tracing are a great way of understanding the dynamics of<br />complex applications. You’ll find a wealth of information in the development<br />log file. When something unexpected happens, this should probably<br />be the first place you look. It’s also worth inspecting the web server log for<br />anomalies. If you use WEBrick in development, this will be scrolling by on<br />the console you use to issue the script/server command.<br />You can add your own messages to the log with Logger object described in<br />the previous section. Sometimes the log files are so busy that it’s hard to<br />find the message you added. In those cases, and if you’re using WEBrick,<br />writing to STDERR will cause your message to appear on the WEBrick console,<br />intermixed with the normal WEBrick tracing..<br />If a page comes up displaying the wrong information, you might want to<br />dump out the objects being passed in from the controller. The debug( )<br />helper method is good for this. It formats objects nicely and makes sure<br />that their contents are valid HTML.<br />&lt;h3&gt;Your Order&lt;/h3&gt;<br />&lt;%= debug(@order) %&gt;<br />&lt;div id="ordersummary"&gt;<br />. . .<br />&lt;/div&gt;<br />Finally, for those problems that just don’t seem to want to get fixed, you<br />can roll out the big guns and point a debugger at your running application.<br />This is normally available only for applications in the development<br />environment.<br /><br />To use breakpoints:<br />1. Insert a call to the method breakpoint( ) at the point in your code where<br />you want your application to first stop. You can pass this method a<br />string if you’d like—this becomes an identifying message later.<br />2. On a convenient console, navigate to your application’s base directory<br />and enter the command<br />depot&gt; ruby script/breakpointer<br />No connection to breakpoint service at<br />druby://localhost:42531 (DRb::DRbConnError)<br />Tries to connect will be made every 2 seconds...<br />Don’t worry about the No connection message—it just means that<br />your breakpoint hasn’t hit yet.<br />3. Using a browser, prod your application to make it hit the breakpoint( )<br />method. When it does, the console where breakpointer is running will<br />burst into life—you’ll be in an irb session, talking to your running<br />web application. You can inspect variables, set values, add other<br />breakpoints, and generally have a good time. When you quit irb, your<br />application will continue running.<br />By default, breakpoint support uses a local network connection to talk<br />between your application and the breakpointer client. You might be able to<br />use the -s option when you run breakpointer to connect to an application on<br />another machine.<img src ="http://www.blogjava.net/wash/aggbug/45387.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wash/" target="_blank">wash</a> 2006-05-10 10:51 <a href="http://www.blogjava.net/wash/archive/2006/05/10/45387.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Active Support</title><link>http://www.blogjava.net/wash/archive/2006/05/10/45371.html</link><dc:creator>wash</dc:creator><author>wash</author><pubDate>Wed, 10 May 2006 02:35:00 GMT</pubDate><guid>http://www.blogjava.net/wash/archive/2006/05/10/45371.html</guid><wfw:comment>http://www.blogjava.net/wash/comments/45371.html</wfw:comment><comments>http://www.blogjava.net/wash/archive/2006/05/10/45371.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wash/comments/commentRss/45371.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wash/services/trackbacks/45371.html</trackback:ping><description><![CDATA[Active Support is a set of libraries that are shared by all Rails components.<br />Much of what’s in there is intended for Rails internal use. However, Active<br />Support also extends some of Ruby’s built-in classes in interesting and<br />useful ways. In this section we’ll quickly list the most popular of these<br />extensions.<br />Extensions to Numbers<br />Class Fixnum gains the two instance methods even? and odd?.<br />All numeric objects gain a set of scaling methods.<br />puts 20.bytes #=&gt; 20<br />puts 20.kilobytes #=&gt; 20480<br />puts 20.megabytes #=&gt; 20971520<br />puts 20.gigabytes #=&gt; 21474836480<br />puts 20.terabytes #=&gt; 21990232555520<br />There are also time-based scaling methods. These convert their receiver<br />into the equivalent number of seconds. The months( ) and years( ) methods<br />are approximations—months are assumed to be 30 days long, years 365<br />days long.<br />puts 20.minutes #=&gt; 1200<br />puts 20.hours #=&gt; 72000<br />puts 20.days #=&gt; 1728000<br />puts 20.weeks #=&gt; 12096000<br />puts 20.fortnights #=&gt; 24192000<br />puts 20.months #=&gt; 51840000<br />puts 20.years #=&gt; 630720000<br />You can also calculate times relative to Time.now using the methods ago( )<br />and from_now( ) (or their aliases until( ) and since( ), respectively).<br />puts Time.now #=&gt; Tue May 10 17:03:43 CDT 2005<br />puts 20.minutes.ago #=&gt; Tue May 10 16:43:43 CDT 2005<br />puts 20.hours.from_now #=&gt; Wed May 11 13:03:43 CDT 2005<br />puts 20.weeks.from_now #=&gt; Tue Sep 27 17:03:43 CDT 2005<br />puts 20.months.ago #=&gt; Thu Sep 18 17:03:43 CDT 2003<br />How cool is that?<br />Time Extensions<br />The Time class gains a number of useful methods, helping you calculate<br />relative times.<br />now = Time.now<br />puts now #=&gt; Tue May 10 17:15:59 CDT 2005<br />puts now.ago(3600) #=&gt; Tue May 10 16:15:59 CDT 2005<br />puts now.at_beginning_of_day #=&gt; Tue May 10 00:00:00 CDT 2005<br />puts now.at_beginning_of_month #=&gt; Sun May 01 00:00:00 CDT 2005<br />puts now.at_beginning_of_week #=&gt; Mon May 09 00:00:00 CDT 2005<br />puts now.at_beginning_of_year #=&gt; Sat Jan 01 00:00:00 CST 2005<br />puts now.at_midnight #=&gt; Tue May 10 00:00:00 CDT 2005<br />puts now.change(:hour =&gt; 13) #=&gt; Tue May 10 13:00:00 CDT 2005<br />puts now.last_month #=&gt; Sun Apr 10 17:15:59 CDT 2005<br />puts now.last_year #=&gt; Mon May 10 17:15:59 CDT 2004<br />puts now.midnight #=&gt; Tue May 10 00:00:00 CDT 2005<br />puts now.monday #=&gt; Mon May 09 00:00:00 CDT 2005<br />puts now.months_ago(2) #=&gt; Thu Mar 10 17:15:59 CST 2005<br />puts now.months_since(2) #=&gt; Sun Jul 10 17:15:59 CDT 2005<br />puts now.next_week #=&gt; Mon May 16 00:00:00 CDT 2005<br />puts now.next_year #=&gt; Wed May 10 17:15:59 CDT 2006<br />puts now.seconds_since_midnight #=&gt; 62159.215938<br />puts now.since(7200) #=&gt; Tue May 10 19:15:59 CDT 2005<br />puts now.tomorrow #=&gt; Wed May 11 17:15:59 CDT 2005<br />puts now.years_ago(2) #=&gt; Sat May 10 17:15:59 CDT 2003<br />puts now.years_since(2) #=&gt; Thu May 10 17:15:59 CDT 2007<br />puts now.yesterday #=&gt; Mon May 09 17:15:59 CDT 2005<br />Active Support also includes a TimeZone class. TimeZone objects encapsulate<br />the names and offset of a time zone. The class contains a list of the<br />world’s time zones. See the Active Support RDoc for details.<br />String Extensions<br />Active Support adds methods to all strings to support the way the Rails<br />core converts names from singular to plural, lowercase to mixed case, and<br />so on. Of these, two might be useful in the average application.<br />puts "cat".pluralize #=&gt; cats<br />puts "cats".pluralize #=&gt; cats<br />puts "erratum".pluralize #=&gt; errata<br />puts "cats".singularize #=&gt; cat<br />puts "errata".singularize #=&gt; erratum<img src ="http://www.blogjava.net/wash/aggbug/45371.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wash/" target="_blank">wash</a> 2006-05-10 10:35 <a href="http://www.blogjava.net/wash/archive/2006/05/10/45371.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Naming Conventions</title><link>http://www.blogjava.net/wash/archive/2006/05/10/45367.html</link><dc:creator>wash</dc:creator><author>wash</author><pubDate>Wed, 10 May 2006 02:28:00 GMT</pubDate><guid>http://www.blogjava.net/wash/archive/2006/05/10/45367.html</guid><wfw:comment>http://www.blogjava.net/wash/comments/45367.html</wfw:comment><comments>http://www.blogjava.net/wash/archive/2006/05/10/45367.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wash/comments/commentRss/45367.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wash/services/trackbacks/45367.html</trackback:ping><description><![CDATA[The rules here are the default conventions used by Rails. You can override<br />all of these conventions using the appropriate declarations in your Rails<br />classes.<br />We often name variables and classes using short phrases. In Ruby, the<br />convention is to have variable names where the letters are all lowercase,<br />and words are separated by <font color="#ff3300">underscores</font>. Classes and modules are named<br />differently: there are no underscores, and each word in the phrase (including<br />the first) is capitalized. (We’ll call this <font color="#ff3333">mixed-case</font>, for fairly obvious<br />reasons). These conventions lead to variable names such as order_status<br />and class names such as LineItem.<br /><br />Rails takes this convention and extends it in two ways. First, it assumes<br />that database table names, like variable names, have lowercase letters and<br />underscores between the words. Rails also assumes that table names are<br />always plural. This leads to table names such as orders and third_parties.<br />On another axis, Rails assumes that files are named in lowercase with<br />underscores.<br />Rails uses this knowledge of naming conventions to convert names automatically.<br />For example, your application might contain a model class that<br />handles line items. You’d define the class using the Ruby naming convention,<br />calling it LineItem. From this name, Rails would automatically deduce<br />the following.<br /><br /><br />That the corresponding database table will be called line_items. That’s<br />the class name, converted to lowercase, with underscores between<br />the words and pluralized.<br />• Rails would also know to look for the class definition in a file called<br />line_item.rb (in the app/models directory).<br /><br />Rails controllers have additional naming conventions. If our application<br />has a store controller, then the following happens.<br />• Rails assumes the class is called StoreController and that it’s in a file<br />named store_controller.rb in the app/controllers directory.<br />• It also assumes there’s a helper module named StoreHelper in the file<br />store_helper.rb located in the app/helpers directory.<br />• It will look for view templates for this controller in the app/views/store<br />directory.<br />• It will by default take the output of these views and wrap them in the<br />layout template contained in store.rhtml or store.rxml in the directory<br />app/views/layouts.<br />There’s one extra twist. In normal Ruby code you have to use the require<br />keyword to include Ruby source files before you reference the classes and<br />modules in those files. Because Rails knows the relationship between<br />filenames and class names, require is not necessary in a Rails application.<br />Instead, the first time you reference a class or module that isn’t known,<br />Rails uses the naming conventions to convert the class name to a filename<br />and tries to load that file behind the scenes. The net effect is that you can<br /><br />Model Naming<br />URL <a href="http://.../store/list">http://.../store/list</a><br />File app/views/store/list.rhtml (or .rxml)<br />View Naming<br />Helper module StoreHelper<br />File app/helpers/store_helper.rb<br />URL <a href="http://.../store/list">http://.../store/list</a><br />Class StoreController<br />File app/controllers/store_controller.rb<br />Controller Naming<br />Method list()<br />Layout app/views/layouts/store.rhtml<br />Figure 13.3: Naming Convention Summary<br /><br />typically reference (say) the name of a model class, and that model will be<br />automatically loaded into your application.<br />As you’ll see, this scheme breaks down when your classes are stored in<br />sessions. In this case you’ll need to explicitly declare them. Even so, you<br />don’t use require. Instead, your controller would include a line such as<br />class StoreController &lt; ApplicationController<br />model :line_item<br /># ...<br />Notice how the naming conventions are still used consistently here. The<br />symbol :line_item is lowercase with an underscore. It will cause the file<br />line_item.rb to be loaded, and that file will contain class LineItem.<br /><br />Grouping Controllers into Modules<br />So far, all our controllers have lived in the app/controllers directory. It is<br />sometimes convenient to add more structure to this arrangement. For<br />example, our store might end up with a number of controllers performing<br />related but disjoint administration functions. Rather than pollute the top-<br />level namespace with each of these, we might choose to group them into a<br />single admin namespace.<br />Rails does this using a simple convention. If an incoming request has a<br />controller named (say) admin/book, Rails will look for the controller called<br />book_controller in the directory app/controllers/admin. That is, the final part<br />of the controller name will always resolve to a file called name_controller.rb,<br />and any leading path information will be used to navigate through subdirectories,<br />starting in the app/controllers directory.<br />Imagine that our application has two such groups of controllers (say,<br />admin/xxx and content/xxx) and that both groups defined a book controller.<br />There’d be a file called book_controller.rb in both the admin and content subdirectories<br />of app/controllers. Both of these controller files would define a<br />class named BookController. If Rails took no further steps, these two classes<br />would clash.<br />To deal with this, Rails assumes that controllers in subdirectories of the<br />directory app/controllers are in Ruby modules named after the subdirectory.<br />Thus, the book controller in the admin subdirectory would be declared as<br />class Admin::BookController &lt; ApplicationController<br /># ...<br />end<br /><br />The book controller in the content subdirectory would be in the Content<br />module.<br />class Content::BookController &lt; ApplicationController<br /># ...<br />end<br />The two controllers are therefore kept separate inside your application.<br />The templates for these controllers appear in subdirectories of app/views.<br />Thus, the view template corresponding to the request<br /><a href="http://my.app/admin/book/edit/1234">http://my.app/admin/book/edit/1234</a><br />will be in the file<br />app/views/admin/book/edit.rhtml<br />You’ll be pleased to know that the controller generator understands the<br />concept of controllers in modules and lets you create them with commands<br />such as<br />myapp&gt; ruby script/generate controller Admin::Book action1 action2 ...<br />This pattern of controller naming has ramifications when we start generating<br />URLs to link actions together. We’ll talk about this starting on<br />page 287.<img src ="http://www.blogjava.net/wash/aggbug/45367.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wash/" target="_blank">wash</a> 2006-05-10 10:28 <a href="http://www.blogjava.net/wash/archive/2006/05/10/45367.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>rails enviroment</title><link>http://www.blogjava.net/wash/archive/2006/05/10/45348.html</link><dc:creator>wash</dc:creator><author>wash</author><pubDate>Wed, 10 May 2006 01:41:00 GMT</pubDate><guid>http://www.blogjava.net/wash/archive/2006/05/10/45348.html</guid><wfw:comment>http://www.blogjava.net/wash/comments/45348.html</wfw:comment><comments>http://www.blogjava.net/wash/archive/2006/05/10/45348.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wash/comments/commentRss/45348.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wash/services/trackbacks/45348.html</trackback:ping><description><![CDATA[The runtime configuration of your application is performed by two files.<br />One, config/environment.rb, is environment independent—it is used regardless<br />of the setting of RAILS_ENV.<br />The second file does depend on the environment:<br />Rails looks for a file named for the current environment in the<br />directory config/environments and loads it during the processing of environment.<br />rb.<br />The standard three environments (development.rb, production.rb,<br />and test.rb) are included by default. You can add your own file if you’ve<br />defined new environment types.<br />Environment files typically do three things.<br />• They set up the Ruby load path. This is how your application can<br />find things such as models and views when it’s running.<br />• They create resources used by your application (such as the logger).<br />• They set various configuration options, both for Rails and for your<br />application.<br /><br />The first two of these are normally application-wide and so are done in<br />environment.rb. The configuration options often vary depending on the environment<br />and so are likely to be set in the environment-specific files in the<br />environments directory.<br /><br />The Load Path<br />The standard environment automatically includes the following directories<br />(relative to your application’s base directory) into your application’s load<br />path.<br />1. test/mocks/environment. As these are first in the load path, classes<br />defined here override the real versions, enabling you to replace live<br />functionality with stub code during testing. This is described starting<br />on page 161.<br />2. All directories whose names start with an underscore or a lowercase<br />letter under app/models and components.子目录<br />3.The directories app, app/models, app/controllers, app/helpers, app/apis,<br />components, config, lib, vendor, and vendor/rails/*.<br />Each of these directories is added to the load path only if it exists.<br /><br />Application-wide Resources<br /><br />environment.rb creates an instance of a Logger that will log messages to<br />log/environment.log. It sets this to be the logger used by Active Record,<br />Action Controller, and Action Mailer (unless your environment-specific<br />configuration files had already set their own logger into any of these components).<br />environment.rb also tells Action Controller and Mailer to use app/views as<br />the starting point when looking for templates. Again, this can be overridden<br />in the environment-specific configurations.<br /><br />Configuration Parameters<br />You configure Rails by setting various options in the Rails modules. Typically<br />you’ll make these settings either at the end of environment.rb (if you<br />want the setting to apply in all environments) or in one of the environmentspecific<br />files in the environments directory.<br />We provide a listing of all these configuration parameters in Appendix B<img src ="http://www.blogjava.net/wash/aggbug/45348.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wash/" target="_blank">wash</a> 2006-05-10 09:41 <a href="http://www.blogjava.net/wash/archive/2006/05/10/45348.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>