- 浏览: 347920 次
- 性别:
- 来自: 福州
文章分类
最新评论
-
18215361994:
chrome扩展中可以获取开发者工具所有资源不?
Chrome 插件开发 -
lBovinl:
完全是一头雾水~o(︶︿︶)o 唉
乱七八糟的Ruby笔记 -
zhangyanan_it:
楼主总结的好多!想问下:map.resources :role ...
Rails随记 -
justin_chiang:
...
Propertiess资源文件的读取和简单的性能测试 -
lezi2012:
感谢分享!!!感谢分享!!!感谢分享!!!感谢分享!!!感谢 ...
Rails随记
绕了不少弯路,感觉这本书上说的还是比较简单
rails是作为ruby的gem进行安装的,需要注意安装相关的依赖包 对于ODBC的连接SQL数据库,需要进行不少的设置,包括控制面板内的管理工具,设置本地的dsn设置 创建rails应用后,可以通过rake db:migrate检查是否配置完成,也可以使用idea来执行判断 数据库database.yml配置如下 development: adapter: sqlserver mode: odbc dsn: CHENHENG username : sa password : 123 其他大体如上 controllers 目录下可以创建对应的c部分,里面创建的文件命名格式为 admin_controller.rb 访问时URL主体部分为admin/action, 其中action为方法名,可以通过直接定义def action来访问自定义的方法 方法执行完,会自动跳转views/admin/目录下的对应action.html.erb类似规则的文件 使用rails建立model时,会自动在db/migrate目录下创建rb文件,可以创建数据库所需的表信息 动态网页内容.两种方式 一:erb, 使用<%=...%>执行ruby,输出变量,与Jsp标签类似 使用<%%>执行ruby语句,循环等,注意end的使用 注意其中<% ...-%>格式的使用,似乎用于去除 所产生的空格 如果需要在<%=%>中输出带特殊字符的ruby代码,可以使用 <%= h("Ann & Bill <frazers@isp.email>" ) %>中的h() 获取action中定义的局部变量的方式@var... 在action中定义的@var变量,可以直接在erb文件中使用<%= @var %>读取 创建超链接的方式, //指向其他的URL,将会忽视对相对和绝对路径的URL处理 修改rails数据库环境的方式,切换development等.. rake db:create RAILS_ENV='development' 在使用Idea开发时,需要注意使用scaffold生成脚手架时,参数格式如下 product title:string desc:text product为model的名称,即数据库中表的名称映射,一般会被映射成复数s的形式 title为列名,string为orm的类型 完整的指令应该为generate scaffold -f product title:string desc:text image_url:string 在开发时,注意不要存在多个不同版本的gem,idea会默认使用最高版本的gem,忽视原有的配置, 可以使用gem uninstall 进行卸载,包括所依赖的相关版本 为已存在的model添加属性,主要目的是为数据库添加列,并且增加所需的记录 generate migration -f add_price_to_product price:decimal 将会生成新的migrate文件,用于记录新增的记录,同时也提供了还原的方式 然后运行rake db:migrate 执行语句即可,如果要在对应的html中进行显示,可以使用 generate scaffold -f product title:string desc:text image_url:string 再次执行生成 添加验证, 在model中添加验证的方式 validates_presence_of :title, :description, :image_url //验证指定的字段非空 validates_numericality_of :price //验证字段必须为数字 添加自定义验证的方式 validate :price_must_be_at_least_a_cent protected def price_must_be_at_least_a_cent errors.add(:price, 'should be at least 0.01' ) if price.nil? ||price < 0.01 //这里主要是errors的使用 end 通过正则进行定义验证的方式 validates_format_of :image_url, :with => %r{\.(gif|jpg|png)$}i, :message => 'must be a URL for GIF, JPG or PNG image.' 通过数据库进行验证 validates_uniqueness_of :title 可以通过建立controller时,可以使用带参数,同时创建action,并且会自动生成对应的erb页面 <%=h ... %> 用于转换内容中的HTML代码 格式化价格 <%= sprintf("$%0.02f" , product.price) %> 货币格式转换的方式 <%= number_to_currency(product.price) %> rails提供了两种用于超链接的标签 button_to 用于生成一个form,并且使用post的提交方法 link_to 用于生成一个简单的a href,使用get方式 创建基于rails本身的session解决数据存储方案 rake db:sessions:create //保存在数据库中 然后执行rake db:migrate ,创建所需的表 在rails2.3中,需要在config/initializers/session_store.rb中配置 Action_controller.session_store = :active_record_store 存储在数据库中,主要用于提供了一种跨多机器的存储环境 建立专属的controller application_controller.rb //注意是必须的重写,内容可以参考框架下的实现,可以直接拷贝 从http请求中获取参数 params[:key] Flash域,用于保存临时显示的数据,原理与struts2类似,同样保存在session中,自动删除 常用于保存错误信息 记录错误信息与flash的使用 logger.error("Attempt to access invalid product #{params[:id]}" ) flash[:notice] = "Invalid product" redirect_to :action => 'index" //URL跳转,重定向,可以通过重构抽取相同的内容到方法中 读取flash的时候,加入if判断是否存在会更好一些 <% if flash[:notice] -%> <div id="notice"><%= flash[:notice] %></div> <% end -%> 判断指定域中对象是否为空的方式 if session[:counter].nil? ,也可以采取||=进行缩写 在页面中使用标签导入其他erb内容,类似jsp的include <%= render(:partial => "cart_item" , :collection => @cart.items) %> 同时在目标中,可以直接包含循环体内容,而不需要重新循环读取 直接集合了c:foreach和include 其中partial为var ,collection为items. 不过功能应该更丰富一些 其中特殊的一点是,只要将需要嵌入的文件命名为_cart_item.html.erb即可自动寻找到,与partial属性相关 :object => @cart 用于传入一个对象 生成一个Ajax请求的标签 <% form_remote_tag :url => { :action => 'add_to_cart', :id => product } do %> <%= submit_tag "Add to Cart" %> <% end %> rjs文件,用于生成所需的js模板文件,使用上与erb类似 在layout文件中,加入以下标签,用于导入默认所需的js文件 <%= javascript_include_tag :defaults %> 在rjs模板中同样适用标签进行声明 page.replace_html("cart" , :partial => "cart" , :object => @cart) 表示替换调用页面中id=cart元素中的html内容 使用内置的effects.js 特效 其中:current_item 为html中元素的id page[:current_item].visual_effect :highlight, :startcolor => "#88ff88", :endcolor => "#114411" 上述代码同样定义在rjs文件中 helpers/ 目录中保存了与controller同名的module文件,用于为对应的controller提供更多功能 将会被自动include,不需要手动编写 在进行渲染时,可以通过判断选择不同的方式 respond_to do |format| format.js if request.xhr? format.html {redirect_to_index} end 在rails建立一对多的主外键关联 在module中添加 一方:has_many :line_items 后者为其他model 多方:belongs_to :order 后者同上 application_controller 作用类似web.xml,用于用代码代替配置工程中的属性 before_filter :authorize, :except => :login 配置过滤器 其中的anthorize protected def authorize unless User.find_by_id(session[:user_id]) flash[:notice] = "Please log in" redirect_to :controller => 'admin' , :action => 'login' end end :except 用于设置例外的界面或请求 创建基于xml的渲染器,类似erb,rjs respond_to do |format| format.html //会根据http header中Accept:内容的不同,自动选择不同的请求render format.xml { render :layout => false } //false用于关闭使用layout模板 end 扩展名如下,使用时候比较特殊一些 who_bought.xml.builder xml.order_list(:for_product => @product.title) do for o in @orders xml.order do xml.name(o.name) xml.email(o.email) end end end 其他情况下,根据路由routes.rb的配置,可以直接使用扩展名,返回不同的渲染 map.connect ':controller/:action/:id.:format 使用内置自动生成xml文件 format.xml { render :layout => false ,:xml => @product.to_xml(:include => :orders) } 调用model的to_xml方法 生成指定格式的feed xml格式文件 format.atom { render :layout => false } 生成JSON 的格式,针对http header请求 format.json { render :layout => false ,:json => @product.to_json(:include => :orders) } 生成文档 rake doc:app i18n/test跳过,不研究 rails项目的目录结构 doc/ 用于存放项目的说明文档 lib/ 可以用于放置一些rb类,可以被controller,view,model中引入,注意需要加上目录 lib/tasks, 用用于放置自定义的take任务 log/用于放置日志信息 public/放置一些静态文件,css,js等,以及404等错误html页面 script/开发用的脚本 vendor/存放第三方插件,代码,用于采用非全局的gem等, 使用项目gem rake rails:freeze:gems 使用系统gem rake rails:unfreeze 其他rake rails:freeze:edge config / 目录 , 用于存放一些配置文件,数据库,环境等 ruby script/server -e development //切换运行环境,参数还包括test,production config/database.yml 数据库连接的配置 Active Support 主要为model中的类,rails为其扩展了许多方便的方法 对于集合的操作,继承了Enumerable中的方法 groups = posts.group_by {|post| post.author_id} state_lookup = us_states.index_by {|state| state.short_name} total_orders = Order.find(:all).sum {|order| order.value } rails也对Array进行了扩展 puts [ "ant" , "bat" , "cat" ].to_sentence #=> "ant, bat, and cat" 对String的扩展也很多...除了字符的截取,还提供了一些英文 单数,复数的转换,大小写格式化 扩展自己的语法转换规则 ActiveSupport::Inflector.inflections do |inflect| inflect.irregular "goose" , "geese" end 对数字同样也提供了扩展 提供了字节,时间的便捷操作 时间和日期的扩展 date = Date.today puts date.tomorrow 以及更多的日期格式化获取 对Ruby语法的扩展,如方法调用 groups = posts.group_by {|post| post.author_id} 转化成 groups = posts.group_by(&:author_id) , 节约了临时对象的编写 Migrations Rails中使用对Migration的维护,来对数据库进行DDL操作,同时对每次的处理,都使用单独的文件进行 保存,便于版本的控制,其中也会将当前项目的db信息保存在表schema_migrations table中 最常见的执行 rake db:migrate,将会比对当前数据库表中与文件的区别,进行执行 对db版本的控制 rake db:migrate VERSION=20080601000010 //将版本调整至指定版本, rake db:migrate:redo STEP=3 //效果一致 常见的列类型,使用在Migration文件中的add_column:属性中 :binary, :boolean, :date, :datetime, :decimal,:float, :integer, :string, :text, :time, and :timestamp. 如:add_column :表名, :column名, :类型 对列的属性设置 :null => true or false //是否允许空 :limit => size //列的长度 :default => value //默认值 decimal类型时候,:precision and :scale 用于设置精度 重命名列 rename_column :orders, :e_mail, :customer_email 修改列属性 change_column :orders, :order_type, :string 重命名表,注意对原有的model代码也会修改 rename_table :order_histories, :order_notes 当添加一些不允许修改的表信息时,可以在self.down中抛出异常,防止错误的修改,导致数据丢失 def self.down raise ActiveRecord::IrreversibleMigration end 对表的创建,注意block的使用 def self.up create_table :order_histories do |t| t.integer :order_id, :null => false t.text :notes t.timestamps end end 定义索引,这里并不很了解,建议需要时查看API add_index :orders, :name,:unique => true orders 为表名称 :name => "somename" 用于指定类名,默认为 unique表示不允许重复 rails创建表时,会自动创建名称为id的主键,也可以自定义 create_table :tickets, :primary_key => :number do |t|...end 创建不包含主键的表 create_table :authors_books, :id => false do |t|..end 可以通过在migration中创建对数据库的增加数据操作,来为测试提供便利,不过感觉数据可能会因此被 固化在migration中,违反了原来的初衷 Loading Data from Fixtures 可以通过定义一些保存数据的yml文件,专门保存数据的内容,然后使用migration进行加载 def self.up down //调用当前的down操作,用于清除数据 directory = File.join(File.dirname(__FILE__), 'dev_data' ) //dev_data用于保存数据yml文件的目录 Fixtures.create_fixtures(directory, "users" )//加载该目录下的users.yml文件 end def self.down User.delete_all end 注意需要引入所需的类 require 'active_record/fixtures' yml中的格式如下 mike: name: Mike Clark status: admin 不过上诉方式,只建议用于加载在开发环境和生产环境下都需要使用的数据,如果要用于加载测试数据,可以用 rake的任务实现 一些时候,比如在修改列的类型,也可以通过在数据库中更新列值,来避免有可能出现的数据丢失 Product.update_all("price = price * 100" ) change_column :products, :price, :integer 使用原生的sql语句 create_table :line_items do |t| t.integer :product_id, :null => false, :options => "CONSTRAINT fk_line_item_products REFERENCES products(id)" execute %{ CREATE TRIGGER #{constraint_name}_delete BEFORE DELETE ON #{to_table} FOR EACH ROW BEGIN SELECT RAISE(ABORT, "constraint violation: #{constraint_name}" ) WHERE (SELECT id FROM #{from_table} WHERE #{from_column} = OLD.id) IS NOT NULL; END; } 对model类的控制 class Sheep < ActiveRecord::Base set_table_name "sheep" #手动设置表名 end 也可以使用self.table_name = "sheep" 在model中也比较特别的一点,就是在model中并不能看到表中的属性,也就是看不到所对应的映射属性,当却可以被正常使用和显示,因为在创建migration时,rails将会自动保存这些信息,如果直接使用scaffold时,也可以自动创建所有的信息.所以并不会重复在model class中显示,包括id 如果需要添加属性,可以通过新建migration来使用 可以通过在命令台执行 ruby script/console Order.column_names 来查看Order model内的列名 对于Boolean值的使用.因为数据库本身的有些支持Boolean,有些则需要使用int或char代替 建议使用user.superuser?进行判断,注意?的使用 然后在model定义该方法,superuser,返回对内部字符的判断返回结果,而不直接依赖数据库中属性 自定义主键列,默认会使用自增的Integer作为主键列,并且使用id进行索引 class LegacyBook < ActiveRecord::Base self.primary_key = "isbn" end 在设置值时,需要使用.id进行设置值,当访问时,使用设置的列名进行访问,使用id来读,使用列名来取,并且保持唯一 在model中类,因为都是继承ActiveRecord类中,所以也会默认使用你所配置的数据库连接 也可以在model中进行覆盖 establish_connection( :adapter => "mysql" , :host => "dbserver.com" , :database => "backend" , :username => "chicho" , :password => "piano" ) CRUD操作 使用model类的 Model.new创建一个新的对象,设置属性后,调用save就可以保存 也可以使用block的方式 Order.new do |o| o.name = "Dave Thomas" # . . . o.save end 也可以通过hash的形式构建对象,在调用save更新到数据库 an_order = Order.new( :name => "Dave Thomas" , :email => "dave@pragprog.com" , :address => "123 Main St" , :pay_type => "check" ) an_order.save 与Hibernate类似,save后,该对象也自动会有id出现 从表单参数中直接创建对象 order = Order.new(params[:order]) //form名字为order 使用create保存对象,无须调用save方法 an_order = Order.create( :name => "Dave Thomas" , :email => "dave@pragprog.com" , :address => "123 Main St" , :pay_type => "check" ) 其实这里的save方法可以理解成hibernate中的saveorupdate方法 create方法可以从array中直接保存一组对象到数据库中 orders = Order.create( [ { :name => "Dave Thomas" , :email => "dave@pragprog.com" , :address => "123 Main St" , :pay_type => "check" }, { :name => "Andy Hunt" , :email => "andy@pragprog.com" , :address => "456 Gentle Drive" , :pay_type => "po" } ] ) 查找对象的方式 Order.find(27) //使用id进行搜索 product_list = params[:product_ids] Product.find(product_list).sum(&:price) 从一组id中获取对象,并计算其中的price属性 Person.find(:first, :conditions=>"name=’Dave’") 带条件的find Give me the first person row that has the name Dave.” 也可以使用:all代替first,表示搜索全部 conditions中带上and ,可以附带更多的搜索条件,其实也就是在sql中带上where从句,注意引号的使用 在参数中,使用#{}带上ruby变量 :conditions => "name = '#{name}' and pay_type = 'po'" 注意以上方法,有可能导致注入的发生 使用?的形式,设置参数 pos = Order.find(:all,:conditions => ["name = ? and pay_type = 'po'" , name]) 使用key的形式,设置参数 pos = Order.find(:all,:conditions => ["name = :name and pay_type = :pay_type" ,{:pay_type => pay_type, :name => name}]) 注意这里的conditions的两种形式字符串与[]数组,其中数组形式的就省去and的使用.会自动进行组合 使用like子句 User.find(:all, :conditions => ["name like ?" , params[:name]+"%" ]). 不能直接使用?+字符串的%拼接 find()中的其他参数 :order sql中的order子句字符串 :limit 在使用:all时,限制返回的数量 :offset 用于分页时,可以限制返回的数据开始的位置:offset => page_num*page_size :joins sql中的join子句 :joins => "as li inner join products as pr on li.product_id = pr.id" 注意:model提供了许多对外键操作的映射方式,所以并不需要经常自定义joins :select 返回需要的列,其实也就是sql中的select中的列 :select => "*, a.name" //用于多表join查询时 :readonly 只读的查询方式 :from 代替table表名的查询方式 :group sql的分组子句 :group => "sku" :lock 设置锁,太麻烦,不研究 使用自定义的sql语句 orders = LineItem.find_by_sql("select line_items.* from line_items, orders where order_id = orders.id and orders.name = 'Dave Thomas' " ) 只要写出标准的格式,rails会自动完成映射,也可以理解成封装成hash的形式,访问时直接使用order.列名进行访问即可 也可以扩展成带参数形式的sql Order.find_by_sql(["select * from orders where amount > ?" ,params[:amount]]) 还提供了对多种列的统计 average = Order.average(:amount) # average amount of orders max = Order.maximum(:amount) min = Order.minimum(:amount) total = Order.sum(:amount) number = Order.count 注意ruby中方法调用时,可以省略掉() result = Order.maximum :amount, :group => "state" , :limit => 3, :order => "max(amount) desc" count的扩展 result1 = Order.count ["amount > ?" , minimum_purchase] Order.count :conditions => "amount > 10" ,:group => "state" 也可以使用自定义的sql语句,注意方法的不同 count = LineItem.count_by_sql("sql...") 动态方法查询,rails提供了多种语义丰富的方法,便于理解和使用 order = Order.find_by_name("Dave Thomas" ) orders = Order.find_all_by_name("Dave Thomas" ) orders = Order.find_all_by_email(params['email' ]) 使用!感叹号,用于在查找不到对象时,抛出异常,而不是返回nil order = Order.find_by_name!("Dave Thomas" ) 更丰富的动态方法 user = User.find_by_name_and_password(name, pw) #多列条件查询 还有更多语义丰富的方法 User.find_all_by_name Cart.find_or_initialize_by_user_id(user.id) 可以通过在model内部添加name_scope,为model添加更多的动态方法 named_scope :last_n_days, lambda { |days| :condition =>['updated < ?' , days] } 调用:orders = Orders.last_n_days(7) 重载加载数据库对象,用于读取出一个对象后,更新该对象为最新的数据库中的属性 Object.reload 更新数据 save方法已经介绍,会自动判断新建还是更新 update属性方法,使用hash的参数形式 order.update_attributes(:name => "Barney",:email => "barney@bedrock.com" ) 常用的还是update 和update_all方法 order = Order.update(12, :name => "Barney" , :email => "barney@bedrock.com" ) #,12为id result = Product.update_all("price = 1.1*price" , "title like '%Java%'" ) save与create方法的!版本 失败都会抛出异常,成功则返回true与完整的record对象 删除数据 Order.delete(123) #id User.delete([2,3,4,5]) #id Product.delete_all(["price > ?" , @expensive_price]) #条件 order.destroy //单个对象,实例级别方法 Order.destroy_all(["shipped_at < ?" , 30.days.ago]) //类级别方法 将Ruby对象序列化到数据库中 class Purchase < ActiveRecord::Base serialize :last_five #声明为存储序列化数据 # ... end 写入 purchase.last_five = [ 'shoes' , 'shirt' , 'socks' , 'ski mask' , 'shorts' ] purchase.save 读取时,将会自动转换成ruby的数组对象,注:列的类型最好为text 将一张表存放在不同的对象之中 class Customer < ActiveRecord::Base composed_of :name, :class_name => 'Name' , ... end 其中name为单独的一个class,并不继承activerecord类 注意其构造函数和内置属性,必须能否与表名内的列名对应 def initialize(first, initials, last) @first = first @initials = initials @last = last end 也可以手动指定所需的列名与字段的映射 composed_of :name,:class_name => "Name" , :mapping =>[ # database ruby %w[ first_name first ], #列名,属性名 %w[ initials initials ], %w[ last_name last ] ] 使用底层的sql连接,来执行sql,并且返回结果 res = Order.connection.select_all("select id, quantity*unit_price as total from line_items" ) 将会返回hash形式的对象数组 注意使用自定义的sql查询时,默认将不会返回id,有此可能造成id确实,update变成create 注意一些rails在table中定义的保留字段的列 created_at, created_on, updated_at, updated_on //记录相关日期 lock_version //锁 id //默认生成的主键 xxx_id //外键中使用 xxx_count //保存子表的字段数目 position //acts_as_list使用时 parent_id //acts_as_tree使用时 type //单表继承使用时 rails也提供了一系列的方法,跟踪对象的变化情况..changed?,name_change等. 类似hibernate,rails也提供了查询的缓存 在rails中也可以通过在表中手动创建_id的外键列方式,来维护主外键关系,注意可以通过创建index,来提高join查询时的性能 常见的关系配置 One-to-One A:belongs_to :order B:has_one :invoice One-to-Many A:belongs_to :order #一方 B:has_many :line_items #多方 Many-to-Many A:has_and_belongs_to_many :products B:has_and_belongs_to_many :categories 无须关心中间表的配置 belongs_to,用于在多方设置,或者理解成外键一方 Declaration in child Foreign Key Parent Class Parent Table belongs_to :product product_id Product products belongs_to :invoice_item invoice_item_id InvoiceItem invoice_items belongs_to :paid_order, :class_name => "Order" , :foreign_key => "order_id" , :conditions => "paid_on is not null" has_one: 在一方设置,属于一对一关系 Declaration Foreign Key Target Class Target Tabl has_one :invoice order_id Invoice invoices 可以使用 :dependent => :destroy 设置级联 has_many:用于设置在一方,表示拥有多个元素 Declaration Foreign Key Target Class Target Table has_many :line_items order_id LineItem line_items 高级设置,可以配置sql查询的方式 has_many :rails_line_items, :class_name => "LineItem" , :finder_sql => "select l.* from line_items l, products p " + " where l.product_id = p.id " + " and p.title like '%rails%'" 还可以设置 :order => "quantity, unit_price DESC" 多表查询时,可以使用:uniq => true属性,来防止出现重复的数据 或者:select => "distinct users.*" 对象生命周期 Object Life Cycle Validation 验证 在model进行save等操作时,都会自动执行验证 也可以自定义进行设置,不同情况下验证的方法 class User < ActiveRecord::Base validate :valid_name? validate_on_create :unique_name? private def valid_name? unless name && name =~ /^\w+$/ errors.add(:name, "is missing or invalid" ) end end 进行验证的时候,注意判断的方法,可以用使用带?的方法,将返回true,而不会跑出异常或者nil 内置的一些验证helper方法 格式验证 validates_format_of :name, :with => /^\w+$/, :message => "is missing or invalid 唯一验证 validates_uniqueness_of :name, :on => :create, #表示开启时机 :message => "is already being used" #错误信息 验证被选择 validates_acceptance_of :terms, :message => "Please accept the terms to proceed" 对相关对象进行验证 validates_associated :line_items, :message => "are messed up" validates_associated :user 验证指定格式字段的值相同, //常用于密码验证 validates_confirmation_of :password 注意html的name属性 <%= password_field "user" , "password" %><br /> <%= password_field "user" , "password_confirmation" %><br /> 循环验证属性 使用block validates_each :name, :email do |model, attr, value| if value =~ /groucho|harpo|chico/i model.errors.add(attr, "You can't be serious, #{value}" ) end end 对集合中内容进行过滤验证 validates_exclusion_of :genre, :in => %w{ polka twostep foxtrot }, :message => "no wild music allowed" 格式验证,也是使用正则 validates_format_of :length, :with => /^\d+(in|cm)/ 验证集合必须包含内容 validates_inclusion_of :gender, :in => %w{ male female }, :message => "should be 'male' or 'female'" 验证长度 validates_length_of :name, :maximum => 50 validates_length_of :password, :in => 6..20 验证数据格式 validates_numericality_of :age, :only_integer => true validates_numericality_of :height_in_meters 非空的属性验证 validates_presence_of :name, :address 验证大小,与length长度使用一致 validates_size_of 验证值的唯一 validates_uniqueness_of :name, :scope => "group_id" //可以设置验证的域 Callbacks 回调函数,也可以理解成监听ActiveRecord操作后,自动执行的方法 使用的方式,只要在class中重载这些方法即可, 如: def before_save self.payment_due ||= Time.now + 30.days end 也可以使用类似validate的方式,使用自定义的函数 before_validation :normalize_credit_card_number protected //注意域 def normalize_credit_card_number self.cc_number.gsub!(/[-\s]/, '' ) end 也可以使用 after_create do |order| logger.info "Order #{order.id} created" end Observers的使用 ActiveRecord::Observer 可以用于监视指定的model类,而无须写入在model中,也提供了复用 根据约定大于配置 OrderObserver将会自动作用于名称为Order的类 如果需要手动控制同时控制多个类,可以使用以下方法 observe Order, Payment, Refund 默认情况下 observer类也放置在model目录下 默认情况下,Active record对象执行查询时,会用hash的方式从数据库中得到对象,再封装到column对象中,如果要自己定义查询时,如.find_by_sql,那么返回的将会是以数组形式保存的hash对象,访问的时候,默认hash的key与sql中的列名相关,也可以使用as语句来进行简化 缓存对象,具体用途不知 def length # ... end memoize :length Transactions 事务 事务的使用 ,手动调用方式 Account.transaction do account1.deposit(100) account2.withdraw(100) end 乐观锁 省略.... Action Controller: Routing and URLs 默认的路由设置 Routing Requests config/routes.rb 文件中 ,如果符合路由设置,将会默认将参数对应的保存在@params变量中,使用hash方式 自定义路由规则时,可以使用script/console 进行测试 depot> ruby script/console >> rs = ActionController::Routing::Routes >> rs.recognize_path "/store" 将会打印出匹配的route规则 如果更新文件后,需要使用下面命令进行加载 >> load "config/routes.rb" map.connect用于设置单条规则,使用方法参数的方式设置参数 在route中,设置了一些默认值,用于对不完整URL的补充 defaults => { :action => "index" , :id => nil } 必须匹配规则 :requirements => { :name =>/regexp/, ...} 条件 :conditions => { :name =>/regexp/orstring, ...} 例子 map.connect 'store/checkout' , :conditions => { :method => :get }, :controller => "store" , :action => "display_checkout_form" 也可以进一步对匹配的内容,进行再验证 map.connect "blog/:year/:month/:day" , :controller => "blog" , :action => "show_date" , :requirements => { :year => /(19|20)\d\d/, :month => /[01]?\d/, :day => /[0-3]?\d/}, :day => nil, :month => nil 生成符合指定route规则的url @link = url_for(:controller => "store" , :action => "display" , :id => 123) 其他的依据路由设置,来便捷实用url的方式 redirect_to(:action => 'delete' , :id => user.id) 可以方便的为model类添加route的rest效果 map.resources :articles # articles为model类名 Rails中controller的方法定义 index 返回model的集合,包含多个对象 create 创建一个model对象,保存到数据库中 POST new 创建一个新资源,当并不保存到数据库中,返回给客户端进行填充 show 根据唯一的条件,返回符合该条件的唯一对象model update根据id更新自定内容 _POST edit 返回根据ID提取出来的内容,填充到界面的编辑表单中 destory 根据id,销毁对象 上诉的操作,都能包含了简单的CRUD操作 route中限制controller中action的方式 map.resources :comments, :except => [:update, :destroy] 这里还是回顾一下.使用内置的scaffold生成包括model在内的rest服务 ruby script/generate scaffold article title:string summary:text content:text controller中创建的环境变量 action_name 当前所处的action名称 cookies cookie中的内容,可以进行读写 headers 一组用hash保存的http请求中的头信息,只用于返回使用,不用来编写cookie params 保存提交上来的参数,form and url request 获取请求的信息,包括http方法等 可以用于访问 protocol://host:port/path?query_string. 对应的所有属性 也可以只用其中的属性,获取客户端信息 request.env['HTTP_ACCEPT_LANGUAGE' ] 包括大量属性的使用,建议有需要的时候直接查看API response ,保存http请求返回内容 session, 会话 填充模板的方法 render() 方法,用于执行填充操作,如果不附带参数,将会自动填充对应的action的模板界面 render(:text =>string) ,使用text为key,添加指定的内容要模板中 render(:inline =>string, [ :type =>"erb"|"builder"|"rjs" ], [ :locals =>hash] ) 添加更详细的参数,可以选择要填充的模板类型 render(:action =>action_name) 调用其他的action模板,注意不会调用其他的action方法 render(:file =>path, [ :use_full_path =>true|false], [:locals =>hash]) 填充指定的模板 render(:template =>name, [:locals =>hash] ) 转发向指定的action,跨controller render(:partial =>name, ...) 填充部分模板 render(:nothing => true) 返回空内容给浏览者 render(:xml =>stuff ) 填充指定的内容为xml,同样会设置Application/xml render(:json =>stuff, [callback =>hash] ) ,返回内容给json,当后面函数未知 render(:update) do |page| ... end 使用block的方式填充一个类似rjs的模板 render还附带了一些通用的参数 :status, :layout, and :content_type :status,用于返回http状态码,正常的为200,不建议返回30x :layout 布尔值,用于设置是否使用模板,似乎还能用于选择其他布局文件 :content_type 设置Content-Type HTTP header 返回其他内容,或者字符的方式 send_data send_data(data, options...) 如:send_data(png_data, :type => "image/png" , :disposition => "inline" ) send_file send_file(path, options...) 将指定的文件发送给客户端 send_file("/files/secret_list" ) Redirects 重定向, 常见的http status code 为301, or 307 redirect_to(:action => 'display'), 如果要传递变量,可以使用flash域进行保存与读取 redirect_to("/help/order_entry.html") 跳转指定的url redirect_to(:action => ..., options...) 跳转指定的action 返回上一页的请求 ----HTTP_REFERER中获取信息 redirect_to(:back) 修改头信息,并重定向 headers["Status" ] = "301 Moved Permanently" redirect_to("http://my.new.home" ) Cookies and Sessions 操作cookie的例子 cookies[:marsupial] = { :value => "wombat" ,:expires => 30.days.from_now,:path => "/store" } 可以在controller中,对session进行设置 session :off, :only => %w{ fetch_rss fetch_atom } rails中有多种对session的存储机制 session_store = :cookie_store 默认的存储机制,在2.0后使用特别的格式进行存储,可以保存任何对象,限制为4k的存储上限 session_store = :p_store 存储在一个flat文件中,使用PStore format格式,可以在environment.rb文件中进行设置文件保存目录 config.action_controller.session_store = CGI::Session::PStore config.action_controller.session_options[:tmpdir] = "/Users/dave/tmp" config.action_controller.session_options[:prefix] = "myapp_session_" session_store = :active_record_store 存储在数据库中 rake db:sessions:create //在数据库中创建所需的表 session_store = :drb_store 使用Ruby的DRb协议,允许在ruby进程之间共享对象,存储在drb服务中,独立web服务 session_store = :mem_cache_store 存储在memcached中 session_store = :memory_store 存储在内存中,对于ruby并不是一个好的处理方法 session_store = :file_store 存储在文件中,但只能保存字符串 可以在controller或者action中 开关session的使用 session :off 也可以附带更多参数 session :off, :only => [ :show, :list ] session :off, :if => proc { Time.now.wday == 0 } Flash: Communicating Between Actions flash,用于在action之间传递参数,是指在重定向操作时,可以将对象保存在flash中进行传递 flash.keep() 可以将flash内的值持久保存在session中,可以带参数保存指定的key对象 Filters and Verification 过滤与验证 rails支持三种类型的过滤器before, after, and around,都是使用def的方法,经过配置规则进行调用 Before and After Filters 使用 before_filter :authorize, :except => :login protected def authorize unless User.find_by_id(session[:user_id]) flash[:notice] = "Please log in" redirect_to :controller => 'admin' , :action => 'login' end end 也可以通过block与class的形式,设置filter before_filter do |controller| logger.info("Processing #{controller.action_name}" ) end after_filter AuditFilter class AuditFilter def self.filter(controller) AuditLog.create(:action => controller.action_name) end end after filter常用于修改返回的内容,比如压缩返回的字符,修改头信息 Around Filters around_filter :time_an_action def time_an_action started = Time.now yield //用于执行代码块 elapsed = Time.now - started logger.info("#{action_name} took #{elapsed} seconds" ) end 同样也可以使用class和block的形式进行设置 这里使用class实例的设置方式 class TimingFilter def filter(controller) started = Time.now yield elapsed = Time.now - started controller.logger.info("#{controller.action_name} took #{elapsed} seconds" ) end end around_filter TimingFilter.new //注意这里使用的是实例 当同时使用两个around_filter时, 执行的顺序为 1 2 .. 2 1 filter可以被子类继承,也可以被重写覆盖 Verification验证 区别于对于字段属性的验证, 是用于权限验证的机制 verify :only => :post_comment, #action 名称 :session => :user_id, #session中的key :add_flash => { :note => "You must log in to comment" }, #错误信息,添加到flash中 :redirect_to => :index #重定向的action 名称 过滤设置 :only =>:name or [ :name, ... ] Verifies only the listed action or actions. :except =>:name or [ :name, ... ] Verifies all actions except those listed. 可以进行判断的内容 :flash =>:key or [ :key, ... ] :method =>:symbol or [ :symbol, ... ] #http 请求方法 :params =>:key or [ :key, ... ] #请求的参数 :session =>:key or [ :key, ... ] :xhr => true or false #是否为ajax请求 Actions 添加值进行传递 :add_flash =>hash :add_headers =>hash #均为:key=>value :redirect_to =>params #使用指定的hash进行重定向 :render =>params #使用指定参数进行渲染设置 Caching 缓存 rails提供了三种缓存 page caching , action caching ,fragment caching, 设置的方式也很简单,只要添加action即可 caches_page :public_content caches_action :premium_content 默认情况下,只有在production环境下才开启缓存,可以通过设置调整 ActionController::Base.perform_caching = true | false config.action_controller.perform_caching = true 对于page的缓存,使用基于url的机制控制页面缓存 清理缓存的方式 expire_page :action => "public_content" expire_action :action => "premium_content" , :id => article 配置缓存策略 多服务器情况下,使用一台专门的服务器放置缓存文件,通过局域网进行读取 ActionController::Base.cache_store = :file_store, "#{RAILS_ROOT}/cache" sweeper 用于专门清理缓存内容的类 app/sweepers: 导入使用: cache_sweeper :article_sweeper, :only => [ :create_article, :update_article, :delete_article ] 设置客户端缓存 在controller中可以设置Expires header expires_in 20.minutes expires_in 1.year 相应的再Apache中,也需要通过配置对于的扩展名添加缓存的http header ExpiresActive On <FilesMatch "\.(ico|gif|jpe?g|png|js|css)$"> ExpiresDefault "access plus 1 year" </FilesMatch> LastModified and ETag Support 304 Not Modified 不过似乎用于只读的使用,没有太大意义,忽略之 使用get获取数据,使用post提交数据,注意方法的使用 Action View 填充的方式 render(:action => 'fake_action_name' ) render(:template => 'controller/name' ) render(:file => 'dir/template' ) rails支持三种模板 builder 用于构建xml的返回内容 erb 用于生成html内容 rjs 用于生成JavaScript内容 environment.rb中配置如下,用于修改erb界面中,设置标签的类型 默认为> <% 3.times do %> Ho!<br/> <% end %> config.action_view.erb_trim_mode = "%" % 5.downto(1) do |i| <%= i %>... <br/> % end 对encode后的参数读取 <%=h params[:name] %> #h的使用 Helpers 的使用,针对controller,可以将部分方法抽取到对于的helper后,直接在页面上使用,减少标签的代码 module StoreHelper def page_title @page_title || "Pragmatic Store" end end <h3><%= page_title %></h3> rails也提供了大量内置的helper,主要为格式化字符串提供了便利 如: <%= number_to_percentage(66.66666, :precision => 1) %> 66.7% 在开发环境下 也可以使用debug获取参数的信息 <%= debug(params) %> Linking to Other Pages and Resources 连接其他资源,提供了一些便利的方法 <%= link_to "Add Comment" , :action => "add_comment" %> <%= link_to "Delete" , { :action => "delete" , :id => @product}, { :class => "dangerous" , :confirm => "Are you sure?" , :method => :delete} %> 提供了很详细的设置 绝对路径的连接 <%= link_to("Help" , "http://my.site/help/index.html" ) %> 还包括了对mail,css等文件的链接生成方式 可以通过安装'will_paginate的gem,为rails添加分页功能 表单的使用 ,(多种) form_for <% form_for :product, :url => { :action => :create } do |form| %> <p>Title: <%= form.text_field :title, :size => 30 %></p> <p>Description: <%= form.text_area :description, :rows => 3 %></p> <p>Image URL: <%= form.text_field :image_url %></p> <p>Price: <%= form.text_field :price, :size => 10 %></p> <%= form.select :title, %w{ one two three } %> <p><%= submit_tag %></p> <% end %> <% form_for :product, :url => { :action => :create, :id => @product }, :html => { :class => "my_form" , :method => :put } do |form| %> 表单字段 Text form.text_field(:attribute, options) form.hidden_field(:attribute, options) form.password_field(:attribute, options) Text Areas form.text_area(:attribute, options) Radio Buttons form.radio_button(:attribute, tag_value, options) Checkboxes form.check_box(:attribute, options, on_value, off_value) Selection Lists form.select(:attribute, choices, options, html_options) 如: <% form_for :user do |form| %> <%= form.select(:name, %w{ Andy Bert Chas Dave Eric Fred }) %> <% end %> 也提供了内置对时间等组件 Multiple Models in a Form 显示model的值 <% form_for :user do |form| %> Name: <%= form.text_field :name %> 通过建立model级别的表关系,可以直接在form中对多表进行直接的处理 scaffold.css文件保存了许多样式设置,可以通过重写,或者自定义的覆盖,来达到自定义的效果 rails 使用Layouts,最大程度的减少了常见的页面内容重复 <%= yield :layout %> 用于在layout中加载内容 默认会使用同名的layout,也可以在controller中进行自定义 layout "standard" layout "standard" , :except => [ :rss, :atom ] 通过方法,动态选择layout def determine_layout if Store.is_closed? "store_down" else "standard" end end 不适用layout的填充 render(:partial => 'article' , :object => @an_article, :locals => { :authorized_by => session[:user_name], :from_ip => request.remote_ip }) 使用layout的填充 <%= render :partial => "user" , :layout => "administrator" %> 共享的填充模板 <%= render("shared/header" , :title => @article.title) %> <%= render(:partial => "shared/post" , :object => @article) %> 部分页面的缓存设置 <% cache do %> <!-- Here's the content we cache --> <ul> <% for article in Article.find_recent -%> <li><p><%= h(article.body) %></p></li> <% end -%> </ul> <% end %> 清理片段缓存的方式 <% cache(:action => 'list', :part => 'articles') do %> <ul> <% for article in @articles -%> <li><p><%= h(article.body) %></p></li> <% end -%> </ul> <% end %> 清理:expire_fragment(:action => 'list' , :part => 'articles' ) 缓存机制选项 ActionController::Base.cache_store = <one of the following> :memory_store, :file_store, "/path/to/cache/directory" :drb_store, "druby://localhost:9192" :mem_cache_store, "localhost" ActionController::Base.cache_store =MyOwnStore.new("parameter") 标签生成的form格式 <input type="text" name="user[password]" /> ssl_requirement gem用于提供ssl的https连接
评论
2 楼
zhangyanan_it
2014-07-02
楼主总结的好多!想问下:
map.resources :roles
:member =>{
:people => :get
}
形成的path怎么是:people_role_url?
很不解?有没有什么资料是描述这个的?
map.resources :roles
:member =>{
:people => :get
}
形成的path怎么是:people_role_url?
很不解?有没有什么资料是描述这个的?
1 楼
lezi2012
2013-08-01
感谢分享!!!感谢分享!!!感谢分享!!!感谢分享!!!感谢分享!!!感谢分享!!!感谢分享!!!感谢分享!!!
相关推荐
### Rails 101 入门电子书知识点详解 #### 一、简介 《Rails 101 入门电子书》是一本非常适合初学者直接入门的书籍,它由xdite编写并出版于2014年6月10日。本书主要针对的是希望学习Ruby on Rails框架的读者,特别...
Ruby on Rails,通常简称为Rails,是一个基于Ruby编程语言的开源Web应用框架,遵循MVC(Model-View-Controller)架构模式。这个“Rails项目源代码”是一个使用Rails构建的图片分享网站的完整源代码,它揭示了如何...
《Rails101_by_rails4.0》是一本专注于Rails 4.0.0版本和Ruby 2.0.0版本的自学教程书籍,它定位于中文读者,旨在成为学习Rails框架的参考教材。Rails(Ruby on Rails)是一个采用Ruby语言编写的开源Web应用框架,它...
Rails 3.1 和 Cucumber-Rails 1.2.0 是两个在Web开发领域非常重要的工具,尤其对于Ruby on Rails框架的测试和自动化流程。本文将深入探讨这两个组件,以及它们如何协同工作来增强软件开发的效率和质量。 首先,...
### Ruby on Rails Guides v2 - Ruby on Rails 4.2.5 #### 一、重要概念及基础假设 - **重要概念**:本指南旨在帮助读者深入理解Ruby on Rails(以下简称Rails)4.2.5版本的核心功能与最佳实践。 - **基础假设**:...
Rails指南中文版是针对Ruby on Rails框架的一份详尽教程,旨在帮助开发者深入理解并熟练掌握这个强大的Web应用开发工具。Ruby on Rails(简称Rails)是一个基于Ruby语言的开源Web应用框架,它遵循MVC(Model-View-...
从给定的文件信息来看,我们正在探讨的是一本关于Ruby on Rails的书籍,书名为《Simply Rails2》,作者是Patrick Lenz。本书旨在为初学者提供深入理解Ruby on Rails框架的指南,从基础概念到高级主题均有涵盖,是...
在开发Web应用时,Ruby on Rails(简称Rails)框架因其高效、简洁的代码风格和强大的社区支持而备受青睐。Aptana是一款强大的集成开发环境(IDE),尤其适用于Rails项目的开发,它提供了丰富的特性来提升开发效率。...
Ruby on Rails 安装指南 Ruby on Rails 安装指南是指安装 Ruby 1.8.6 和 Rails 2.0.2 的详细步骤。首先,需要下载 Ruby One-Click Installer 版本,并安装 Ruby。然后,下载 Rails 2.0.2 版本,并安装。接下来,...
[Pragmatic Bookshelf] Crafting Rails Applications Expert Practices for Everyday Rails Development (E-Book) ☆ 图书概要:☆ Rails 3 is a huge step forward. You can now easily extend the framework, ...
在本文中,我们将深入探讨如何使用Rails敏捷开发技术构建一个购物车系统,特别是在参考《rails敏捷开发第四版》中的示例。Rails 3.2.6是本文的基础框架,它是一个强大的Ruby Web应用程序框架,以其MVC(模型-视图-...
标题 "Rails" 指的是 Ruby on Rails,一个开源的Web应用程序框架,它基于Ruby编程语言,遵循MVC(模型-视图-控制器)架构模式。Rails由David Heinemeier Hansson在2004年创建,其设计理念是强调代码的简洁性、DRY...
rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails ...
Ruby on Rails,简称Rails,是一种基于Ruby语言的开源Web应用程序框架,它遵循MVC(Model-View-Controller)架构模式,旨在使Web开发过程更加高效、简洁。本篇将通过一个入门实例,深入探讨Rails的基本概念和核心...
Rails Recipes是一本针对Ruby on Rails框架的实用书籍,它收集了一系列高效解决问题的技巧和方法,也被称为“Rails开发者的宝典”。作者们通过分享自己的经验和见解,为Rails程序员提供了一本既有实际操作指导又有...
Rails是Ruby语言的一个著名Web开发框架,全称为Ruby on Rails,它遵循MVC(Model-View-Controller)架构模式,旨在提高开发效率和代码可读性。本示例"rails项目起步示例"是一个购物系统,非常适合初学者入门学习。 ...
**中文版Rails教程** Rails,全称为Ruby on Rails,是一个基于Ruby编程语言的开源Web应用程序框架,遵循MVC(模型-视图-控制器)架构模式。Rails以其“约定优于配置”(Convention over Configuration)和“Don't ...
Rails是Ruby编程语言的一个著名框架,用于开发Web应用程序。它以MVC(模型-视图-控制器)架构模式为基础,提供了许多内置功能,使开发者能够更高效地编写代码。在这个"rails本地安装包完整版"中,包含了Rails 2.1.0...
本书《Component-Based Rails Applications》主要介绍了如何使用Rails引擎(Rails Engine)进行基于组件的Rails应用开发,以及如何对应用程序的大型模块进行拆分和模块化。以下是书中一些核心知识点的详细说明: 1....