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