- 浏览: 403840 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
冯大圆__渐成胡子渣:
写得很详细,想请求一下,bundler install的时候设 ...
Rails Assets Pipeline -
DaSunWarman:
...
#!/usr/bin/env 脚本解释程序的作用 -
alexag:
...
javascript立即执行函数与函数声明和函数表达式 -
houxm:
你也可以使用更简单的方式(只要在元素上添加 data-togg ...
bootstrap 小tip -
jaycongwen:
帮我看看啊,我刚学wen@wen-desktop:~$ cd ...
cannot load such file -- openssl
原文出处:
http://zires.info/2011/02/rails3-%E5%88%9D%E5%A7%8B%E5%8C%96%E5%92%8C%E5%90%AF%E5%8A%A8-initialization-process/
参考链接:
http://blog.csdn.net/tomwang1013/article/details/8657191
http://blog.csdn.net/tomwang1013/article/details/8691335
一直想搞清楚rails的启动和整个生命进程,好在有官方的guide用来参考,The Rails Initialization Process。
1)先来看看rails的组织结构
%w(
actionmailer
actionpack
activemodel
activerecord
activeresource
activesupport
railties
)
2)rails是如何启动的?
按下‘rails s’ 命令发生了什么?
rails3中rails已经变成了一个全局的命令,s是它的参数,s是server的缩写。
rails命令在gem包的bin/rails脚本中
#!/usr/bin/env ruby
begin
require "rails/cli"
rescue LoadError
railties_path = File.expand_path('../../railties/lib', __FILE__)
$:.unshift(railties_path)
require "rails/cli"
end
如果找不到rails/cli就把railties_path加到当前环境变量中。railties作用是将每个rails模块串联起来,它负责rails的启动顺序,管理rails的命令行接口,并且提供Rails的generators。
” rails/cli ” 是负责什么的?
require 'rbconfig'
require 'rails/script_rails_loader'
# If we are inside a Rails application this method performs an exec and thus
# the rest of this script is not run.
Rails::ScriptRailsLoader.exec_script_rails!
require 'rails/ruby_version_check'
Signal.trap("INT") { puts; exit(1) }
if ARGV.first == 'plugin'
ARGV.shift
require 'rails/commands/plugin_new'
else
require 'rails/commands/application'
end
rbconfig是对ruby标准库的配置和补充,在ruby编译的时候起效,和rails关系不大,不谈。
走进script_rails_loader.rb文件,里面定义了两个常量
RUBY = File.join(*RbConfig::CONFIG.values_at("bindir", "ruby_install_name")) + RbConfig::CONFIG["EXEEXT"]
SCRIPT_RAILS = File.join('script', 'rails')
RUBY是ruby的bin文件位置,不管是Mac OS还是Windows还是其他,都会指向可执行文件。
SCRIPT_RAILS就是指向rails生成项目script目录下的rails脚本。大体内容如下:
#!/usr/bin/env ruby
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
APP_PATH = File.expand_path('../../config/application', __FILE__)
require File.expand_path('../../config/boot', __FILE__)
require 'rails/commands'
回到cli文件中,下一句可以看到执行了一个方法
Rails::ScriptRailsLoader.exec_script_rails!
exec_script_rails!方法的内容:
def self.exec_script_rails!
cwd = Dir.pwd
return unless in_rails_application? || in_rails_application_subdirectory?
exec RUBY, SCRIPT_RAILS, *ARGV if in_rails_application?
Dir.chdir("..") do
# Recurse in a chdir block: if the search fails we want to be sure
# the application is generated in the original working directory.
exec_script_rails! unless cwd == Dir.pwd
end
exec RUBY, SCRIPT_RAILS, *ARGV 这边大致上可以看出端倪了,这行代码的实质是:
ruby script/rails [arguments]
# 这里的arguments 可以是server, generate, console等
OK,重点来看看script/rails
首先有一个APP_PATH的常量,可以看到指向的是config目录下的application.rb文件。接着require了boot文件和commands文件。这里可以看到boot文件是第一个被载入的。
boot文件的任务其实很简单,就是准备好Gemfile中的gems。
# rubygems第一个被加载
require 'rubygems'
# Set up gems listed in the Gemfile.
gemfile = File.expand_path('../../Gemfile', __FILE__)
begin
ENV['BUNDLE_GEMFILE'] = gemfile
require 'bundler'
Bundler.setup
rescue Bundler::GemNotFound => e
STDERR.puts e.message
STDERR.puts "Try running `bundle install`."
exit!
end if File.exist?(gemfile)
命令行的实质就全在rails/commands.rb中了,源码地址commands.rb
ARGV < < '--help' if ARGV.empty?
aliases = {
"g" => "generate",
"c" => "console",
"s" => "server",
"db" => "dbconsole"
}
command = ARGV.shift
command = aliases[command] || command
可以看到这里的ARGV就是上面提到的exec RUBY, SCRIPT_RAILS, *ARGV后面的参数,也就是我们传进去的”server,generate,console”等等。这里为空就是”–help”,并且还有4个aliases方便简写。
主要还是看server是如何启动的。
when 'server'
# Change to the application's path if there is no config.ru file in current dir.
# This allows us to run script/rails server from other directories, but still get
# the main config.ru and properly set the tmp directory.
Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exists?(File.expand_path("config.ru"))
require 'rails/commands/server'
Rails::Server.new.tap { |server|
# We need to require application after the server sets environment,
# otherwise the --environment option given to the server won't propagate.
require APP_PATH
Dir.chdir(Rails.application.root)
server.start
}
上面代码有三点,第一是实例化了Rails::server,第二是require APP_PATH(也就是application.rb),第三调用了server#start方法
实例化了一个Rails::Server,这是个什么东东?参考源码commands/server.rb
require 'fileutils'
require 'optparse'
require 'action_dispatch'
module Rails
class Server < ::Rack::Server
......
end
end
原来Rails::Server继承了Rack::Server(终于和Rack挂钩了),Rack::Server用来给所有基于rack的应用提供一般的server接口。而且,这里第一次引入了action_dispatch。Rails::Server的initialize方法如下:
def initialize(*)
super
set_environment
end
super,Rack::Server源码那么Rack::Server的initialize方法如下:
def initialize(options = nil)
@options = options
@app = options[:app] if options && options[:app]
end
由于options为nil所以Rack::Server中的initialize无作为,回到Rails::Server中,super的下一句是set_environment,代码如下:
def set_environment
ENV["RAILS_ENV"] ||= options[:environment]
end
一目了然,设定环境咯,production,development,还是test。这里options是父类Rack::Server中的:
def options
@options ||= parse_options(ARGV)
end
def parse_options(args)
options = default_options
# Don't evaluate CGI ISINDEX parameters.
# http://hoohoo.ncsa.uiuc.edu/cgi/cl.html
args.clear if ENV.include?("REQUEST_METHOD")
options.merge! opt_parser.parse! args
options[:config] = ::File.expand_path(options[:config])
ENV["RACK_ENV"] = options[:environment]
options
end
default_options在Rails::Server中被覆写了:
def default_options
super.merge({
:port => 3000,
:environment => (ENV['RAILS_ENV'] || "development").dup,
:daemonize => false,
:debugger => false,
:pid => File.expand_path("tmp/pids/server.pid"),
:config => File.expand_path("config.ru") # config.ru被指定,这也是commands.rb中server要chdir项目根目录的原因。
})
end
第二是require APP_PATH(也就是application.rb),其实就是将项目的application给配置好,里面有这么一句:
require 'rails/all'
其实就是将rails所有的模块都引入进来,all.rb如下:
require "rails"
%w(
active_record
action_controller
action_mailer
active_resource
rails/test_unit
).each do |framework|
begin
require "#{framework}/railtie"
rescue LoadError
end
end
第三是调用了server#start方法,在Rails::Server中:
def start
puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}"
puts "=> Rails #{Rails.version} application starting in #{Rails.env} on http://#{options[:Host]}:#{options[:Port]}"
puts "=> Call with -d to detach" unless options[:daemonize]
trap(:INT) { exit }
puts "=> Ctrl-C to shutdown server" unless options[:daemonize]
#Create required tmp directories if not found
%w(cache pids sessions sockets).each do |dir_to_make|
FileUtils.mkdir_p(Rails.root.join('tmp', dir_to_make))
end
super
ensure
# The '-h' option calls exit before @options is set.
# If we call 'options' with it unset, we get double help banners.
puts 'Exiting' unless @options && options[:daemonize]
end
多熟悉啊,先一步步的屏显。然后是trap(:INT) { exit },是响应Ctrl-C中断的。再创建了tmp文件夹和四个子文件夹,最后回到Rack::Server的start方法中。
Rack::Server的start方法有这么一句:
wrapped_app
实际调用的是:
def wrapped_app
@wrapped_app ||= build_app app
end
这里有两个方法的调用,一个是#build_app,另一个是#app,先来看#app方法:
def app
@app ||= begin
if !::File.exist? options[:config]
abort "configuration #{options[:config]} not found"
end
app, options = Rack::Builder.parse_file(self.options[:config], opt_parser)
self.options.merge! options
app
end
end
了然了,原来通过Rack::Builder和config.ru构建了一个Rack application啊.Rack::Builder源码
再来看#build_app方法:
def build_app(app)
middleware[options[:environment]].reverse_each do |middleware|
middleware = middleware.call(self) if middleware.respond_to?(:call)
next unless middleware
klass = middleware.shift
app = klass.new(app, *middleware)
end
app
end
通过middleware来新建一个app,像剥洋葱一样,一个一个middleware的往外套。
ok,由上面我们知道,通过config.ru,我们创建了一个Rack Application,下面来看看config.ru
# This file is used by Rack-based servers to start the application.
require ::File.expand_path('../config/environment', __FILE__)
run example::Application
可以看到引入了environment.rb文件。如下:
# Load the rails application
require File.expand_path('../application', __FILE__)
# Initialize the rails application
example::Application.initialize!
初始化了example::Application,example::Application是继承的Rails::Application,那么Rails::Application是什么呢?
#Rails::Application is responsible for executing all railties, engines and plugin
# initializers. Besides, it also executed some bootstrap initializers (check
# Rails::Application::Bootstrap) and finishing initializers, after all the others
# are executed (check Rails::Application::Finisher).
通过代码,Rails::Application继承了Engine。
看看initialize!方法:
def initialize!
raise "Application has been already initialized." if @initialized
run_initializers(self)
@initialized = true
self
end
至此,Rails Application的初始化和Rails Server基本上都已经启动完成。
http://zires.info/2011/02/rails3-%E5%88%9D%E5%A7%8B%E5%8C%96%E5%92%8C%E5%90%AF%E5%8A%A8-initialization-process/
参考链接:
http://blog.csdn.net/tomwang1013/article/details/8657191
http://blog.csdn.net/tomwang1013/article/details/8691335
一直想搞清楚rails的启动和整个生命进程,好在有官方的guide用来参考,The Rails Initialization Process。
1)先来看看rails的组织结构
%w(
actionmailer
actionpack
activemodel
activerecord
activeresource
activesupport
railties
)
2)rails是如何启动的?
按下‘rails s’ 命令发生了什么?
rails3中rails已经变成了一个全局的命令,s是它的参数,s是server的缩写。
rails命令在gem包的bin/rails脚本中
#!/usr/bin/env ruby
begin
require "rails/cli"
rescue LoadError
railties_path = File.expand_path('../../railties/lib', __FILE__)
$:.unshift(railties_path)
require "rails/cli"
end
如果找不到rails/cli就把railties_path加到当前环境变量中。railties作用是将每个rails模块串联起来,它负责rails的启动顺序,管理rails的命令行接口,并且提供Rails的generators。
” rails/cli ” 是负责什么的?
require 'rbconfig'
require 'rails/script_rails_loader'
# If we are inside a Rails application this method performs an exec and thus
# the rest of this script is not run.
Rails::ScriptRailsLoader.exec_script_rails!
require 'rails/ruby_version_check'
Signal.trap("INT") { puts; exit(1) }
if ARGV.first == 'plugin'
ARGV.shift
require 'rails/commands/plugin_new'
else
require 'rails/commands/application'
end
rbconfig是对ruby标准库的配置和补充,在ruby编译的时候起效,和rails关系不大,不谈。
走进script_rails_loader.rb文件,里面定义了两个常量
RUBY = File.join(*RbConfig::CONFIG.values_at("bindir", "ruby_install_name")) + RbConfig::CONFIG["EXEEXT"]
SCRIPT_RAILS = File.join('script', 'rails')
RUBY是ruby的bin文件位置,不管是Mac OS还是Windows还是其他,都会指向可执行文件。
SCRIPT_RAILS就是指向rails生成项目script目录下的rails脚本。大体内容如下:
#!/usr/bin/env ruby
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
APP_PATH = File.expand_path('../../config/application', __FILE__)
require File.expand_path('../../config/boot', __FILE__)
require 'rails/commands'
回到cli文件中,下一句可以看到执行了一个方法
Rails::ScriptRailsLoader.exec_script_rails!
exec_script_rails!方法的内容:
def self.exec_script_rails!
cwd = Dir.pwd
return unless in_rails_application? || in_rails_application_subdirectory?
exec RUBY, SCRIPT_RAILS, *ARGV if in_rails_application?
Dir.chdir("..") do
# Recurse in a chdir block: if the search fails we want to be sure
# the application is generated in the original working directory.
exec_script_rails! unless cwd == Dir.pwd
end
exec RUBY, SCRIPT_RAILS, *ARGV 这边大致上可以看出端倪了,这行代码的实质是:
ruby script/rails [arguments]
# 这里的arguments 可以是server, generate, console等
OK,重点来看看script/rails
首先有一个APP_PATH的常量,可以看到指向的是config目录下的application.rb文件。接着require了boot文件和commands文件。这里可以看到boot文件是第一个被载入的。
boot文件的任务其实很简单,就是准备好Gemfile中的gems。
# rubygems第一个被加载
require 'rubygems'
# Set up gems listed in the Gemfile.
gemfile = File.expand_path('../../Gemfile', __FILE__)
begin
ENV['BUNDLE_GEMFILE'] = gemfile
require 'bundler'
Bundler.setup
rescue Bundler::GemNotFound => e
STDERR.puts e.message
STDERR.puts "Try running `bundle install`."
exit!
end if File.exist?(gemfile)
命令行的实质就全在rails/commands.rb中了,源码地址commands.rb
ARGV < < '--help' if ARGV.empty?
aliases = {
"g" => "generate",
"c" => "console",
"s" => "server",
"db" => "dbconsole"
}
command = ARGV.shift
command = aliases[command] || command
可以看到这里的ARGV就是上面提到的exec RUBY, SCRIPT_RAILS, *ARGV后面的参数,也就是我们传进去的”server,generate,console”等等。这里为空就是”–help”,并且还有4个aliases方便简写。
主要还是看server是如何启动的。
when 'server'
# Change to the application's path if there is no config.ru file in current dir.
# This allows us to run script/rails server from other directories, but still get
# the main config.ru and properly set the tmp directory.
Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exists?(File.expand_path("config.ru"))
require 'rails/commands/server'
Rails::Server.new.tap { |server|
# We need to require application after the server sets environment,
# otherwise the --environment option given to the server won't propagate.
require APP_PATH
Dir.chdir(Rails.application.root)
server.start
}
上面代码有三点,第一是实例化了Rails::server,第二是require APP_PATH(也就是application.rb),第三调用了server#start方法
实例化了一个Rails::Server,这是个什么东东?参考源码commands/server.rb
require 'fileutils'
require 'optparse'
require 'action_dispatch'
module Rails
class Server < ::Rack::Server
......
end
end
原来Rails::Server继承了Rack::Server(终于和Rack挂钩了),Rack::Server用来给所有基于rack的应用提供一般的server接口。而且,这里第一次引入了action_dispatch。Rails::Server的initialize方法如下:
def initialize(*)
super
set_environment
end
super,Rack::Server源码那么Rack::Server的initialize方法如下:
def initialize(options = nil)
@options = options
@app = options[:app] if options && options[:app]
end
由于options为nil所以Rack::Server中的initialize无作为,回到Rails::Server中,super的下一句是set_environment,代码如下:
def set_environment
ENV["RAILS_ENV"] ||= options[:environment]
end
一目了然,设定环境咯,production,development,还是test。这里options是父类Rack::Server中的:
def options
@options ||= parse_options(ARGV)
end
def parse_options(args)
options = default_options
# Don't evaluate CGI ISINDEX parameters.
# http://hoohoo.ncsa.uiuc.edu/cgi/cl.html
args.clear if ENV.include?("REQUEST_METHOD")
options.merge! opt_parser.parse! args
options[:config] = ::File.expand_path(options[:config])
ENV["RACK_ENV"] = options[:environment]
options
end
default_options在Rails::Server中被覆写了:
def default_options
super.merge({
:port => 3000,
:environment => (ENV['RAILS_ENV'] || "development").dup,
:daemonize => false,
:debugger => false,
:pid => File.expand_path("tmp/pids/server.pid"),
:config => File.expand_path("config.ru") # config.ru被指定,这也是commands.rb中server要chdir项目根目录的原因。
})
end
第二是require APP_PATH(也就是application.rb),其实就是将项目的application给配置好,里面有这么一句:
require 'rails/all'
其实就是将rails所有的模块都引入进来,all.rb如下:
require "rails"
%w(
active_record
action_controller
action_mailer
active_resource
rails/test_unit
).each do |framework|
begin
require "#{framework}/railtie"
rescue LoadError
end
end
第三是调用了server#start方法,在Rails::Server中:
def start
puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}"
puts "=> Rails #{Rails.version} application starting in #{Rails.env} on http://#{options[:Host]}:#{options[:Port]}"
puts "=> Call with -d to detach" unless options[:daemonize]
trap(:INT) { exit }
puts "=> Ctrl-C to shutdown server" unless options[:daemonize]
#Create required tmp directories if not found
%w(cache pids sessions sockets).each do |dir_to_make|
FileUtils.mkdir_p(Rails.root.join('tmp', dir_to_make))
end
super
ensure
# The '-h' option calls exit before @options is set.
# If we call 'options' with it unset, we get double help banners.
puts 'Exiting' unless @options && options[:daemonize]
end
多熟悉啊,先一步步的屏显。然后是trap(:INT) { exit },是响应Ctrl-C中断的。再创建了tmp文件夹和四个子文件夹,最后回到Rack::Server的start方法中。
Rack::Server的start方法有这么一句:
wrapped_app
实际调用的是:
def wrapped_app
@wrapped_app ||= build_app app
end
这里有两个方法的调用,一个是#build_app,另一个是#app,先来看#app方法:
def app
@app ||= begin
if !::File.exist? options[:config]
abort "configuration #{options[:config]} not found"
end
app, options = Rack::Builder.parse_file(self.options[:config], opt_parser)
self.options.merge! options
app
end
end
了然了,原来通过Rack::Builder和config.ru构建了一个Rack application啊.Rack::Builder源码
再来看#build_app方法:
def build_app(app)
middleware[options[:environment]].reverse_each do |middleware|
middleware = middleware.call(self) if middleware.respond_to?(:call)
next unless middleware
klass = middleware.shift
app = klass.new(app, *middleware)
end
app
end
通过middleware来新建一个app,像剥洋葱一样,一个一个middleware的往外套。
ok,由上面我们知道,通过config.ru,我们创建了一个Rack Application,下面来看看config.ru
# This file is used by Rack-based servers to start the application.
require ::File.expand_path('../config/environment', __FILE__)
run example::Application
可以看到引入了environment.rb文件。如下:
# Load the rails application
require File.expand_path('../application', __FILE__)
# Initialize the rails application
example::Application.initialize!
初始化了example::Application,example::Application是继承的Rails::Application,那么Rails::Application是什么呢?
#Rails::Application is responsible for executing all railties, engines and plugin
# initializers. Besides, it also executed some bootstrap initializers (check
# Rails::Application::Bootstrap) and finishing initializers, after all the others
# are executed (check Rails::Application::Finisher).
通过代码,Rails::Application继承了Engine。
看看initialize!方法:
def initialize!
raise "Application has been already initialized." if @initialized
run_initializers(self)
@initialized = true
self
end
至此,Rails Application的初始化和Rails Server基本上都已经启动完成。
发表评论
-
ruby module :: 前置操作符
2014-04-02 16:55 713在ruby代码中,我们经常看到有类似这样的获取module的用 ... -
关于Ruby动态方法定义的区别
2014-04-02 16:05 833A.class_eval(<<-EOF, __ ... -
%Q, %q, %W, %w, %x, %r, %s
2014-04-02 10:52 1003%Q 遇到引号嵌套的时候我们往往需要使用反斜线来实现转义,使用 ... -
Ruby extend self
2013-10-22 10:14 915我们想让实例方法同时为类方法,那么可以使用extend sel ... -
$:.unshift File.expand_path('..', __FILE__)
2013-10-22 10:05 1279一直能看到一些gem里面会有这样一句代码: $:.unshif ... -
rails cattr_accessor and mattr_accessor
2013-09-27 09:37 0http://stackoverflow.com/questi ... -
Rails、Nginx、Passenger、bundle,这几者是怎么协作的?
2013-06-27 00:33 1078注:本文转自知乎,原文请参考 Bundle是Gem包的依赖管 ... -
bundle open a specify gem
2013-06-26 23:48 992今天在看railscasts教程http://railscas ... -
关于测试
2013-06-25 00:52 678http://asciicasts.com/episodes/ ... -
Rails高级编程 笔记
2013-04-23 18:00 0Ruby基础 1、类:主要负责封装和分离事物 2 ... -
ruby通用符号
2013-04-10 22:34 0%Q 当你在”字符串中” 有大量的使用双引号时,频繁的转义字符 ... -
rails_client_validations
2013-02-22 10:57 875看了下rails的服务端验证怎样转换到客户端,实现类似于aja ... -
rails Authration and Password
2013-02-19 18:23 972以下是我总结的在rails项目中用到的与登录注册相关的资源: ... -
Rails Assets Pipeline
2013-02-03 18:03 7305Assets Pipeline 有什么好处 ... -
deployment RoR with nginx & unicorn on ubuntu
2013-01-09 14:50 1819本来一直都是用rails自带的webrick做本地开发的,但是 ... -
rails attr_protected、 attr_accessible
2013-01-06 10:02 1005attr_protected、 attr_accessible ... -
NewRelic
2013-01-04 17:52 6281NewRelic是一家提供Rails性能监测服务的网站, Ne ... -
rails中处理北京时间以及数据库的时区问题
2012-10-10 11:18 0解释4个时区设置的不同: config.active_rec ... -
eigenclass 与 class 关系
2012-09-20 16:24 1076声明:本文转载自http://ruanwz.github.co ... -
单例模块儿
2012-09-11 17:01 919#单例模块,存在的意义就是在模块被载入类时,给类添加类方法和创 ...
相关推荐
rails server命令启动web服务器的默认端口号为3000,当然我们也可以自定义指定端口号。
The Rails™ 3 Way is a comprehensive resource that digs into the new features in Rails 3 and perhaps more importantly, the rationale behind them. —Yehuda Katz, Rails Core The Bible for Ruby on ...
Ruby on Rails strips complexity from the development process, enabling professional developers to focus on what matters most: delivering business value via clean and maintainable code. The Rails™ 3 ...
NULL 博文链接:https://michael-roshen.iteye.com/blog/1731372
Rails 3 in Action 2011年9月新鲜出炉,针对最新的Rails 3.1进行说明
Windows7_Cygwin_Git_RVM_Ruby1.9.3_Rails3_MongoD B_Nginx_Unicorn_Rspec_Guard_Spork(2-Ruby on Rails3 安装配置
turbo-sprockets-rails3, 加速你的Rails 3资产 用于 Rails 3.2.x的涡轮链轮 通过只根据源文件的哈希来重新编译已经更改的资产,从而加快 Rails 3 rake assets:precompile的速度只编译一次以生成指纹和非打印的资产...
Ruby+on+Rails+3+Tutorial.pdf 应用Rails进行敏捷Web开发第4版.pdf (Agile Web Development with Rails) Rails.Recipes.Rails.3.Edition.pdf
Rails3消息队列系统 Sidekiq
《Rails之道》按照Rails的各个子系统进行组织编排,分别介绍了Rails的环境、初始过程、配置和日志记录,Rails的分配器、控制器、页面生成和路由,REST、资源和Rails,ActiveRecord的基础、关联、验证和高级技巧,...
jquery-rails, 一个 gem,用于自动使用jQuery和 Rails 3 railsjQuery 面向 Rails 如此伟大。这里 gem 提供:jQuery 1.7.2jQuery UI 1.8.18 ( 仅适用于 javascript )jQuery UJS适配器assert_select_j
rails3的英文文档
Rails3的ActiveRecord 查询API.doc
rails常用命令,例如新建rails项目,新建controller、model 等等
rails_apps_composer, 一个 gem,为 Rails 启动应用程序创建 Rails 应用程序模板 Rails 应用编辑器 Rails 应用程序编辑器 gem 安装一个 命令行 工具来从"食谱"的Collection 组装 Rails 应用程序。"你可以使用 rails_...
基于java的开发源码-Rails3消息队列系统 Sidekiq.zip 基于java的开发源码-Rails3消息队列系统 Sidekiq.zip 基于java的开发源码-Rails3消息队列系统 Sidekiq.zip 基于java的开发源码-Rails3消息队列系统 Sidekiq.zip ...
ruby on rails开发的初学者很适合的工具书,易上手,很实用,
This pioneering book is the first resource that deep dives into the new Rails 3 APIs and shows you how use them to write better web applications and make your day-to-day work with Rails more ...
rails 项目起步示例 同新手共同进步