1、首先利用rails depot建立rails应用,进入depot目录
//2、在depot目录下建立数据库 mysqladmin -u root create depot_development
配置应用时,可直接利用命令ranlis --database mysql depot,同时生成与depot应用相关的数据库depot_development
2、测试配置是否无误:
rake db:migrate
检查是否能连到数据库,在MySQL下,用mysql -u root depot_development
检查是否能建表:mysql> create table dummy(i int); mysql> drop table dummy;
3、创建products model 和maintenance application
通过ruby script/generate scaffold ModelName ControlerName
现在,我们建立了一个depot应用,并且建立了一个数据库连接到depot project.我们创建了一个product controller和product model,使用migration传教相应的products表
4、运行ruby script/server
改进2
1、表中增加一列:depot> ruby script/generate migration add_price_to_product price:decimal
2、修改add_price_product方法
3、rake db:migrate实现修改model即数据库中表后的应用
4、注意我们上面只关注了model层,control层未作改动,现在我们还需要做的就是修改view层。
文件depot_a/app/views/products/index.html.erb为显示层代码,需加入列price的显示
改进3 验证
1、validate的使用,注意,我在先前加入列image_url时,错写成了imag_url
改进4 优化页面显示
1、增加测试数据,先迁移:ruby script/generate migration add_test_data1
然后修改add_test_data方法
2、找到相应美化的图片和css放到public的stylesheet目录下
3、修改*add_test_data1文件
4、rake db:migrate完成更新
Task B Catalog Display
B1 创建目录列表:
1、ruby script/generate controller store index , 用来建立一个新的控制器,控制器中的方法index,似乎一个控制器对应一个页面,用控制器的名称作为路径可以访问,因为在view中自动生成了控制器store的一个目录
2、修改控制器类的index方法,使它能调用Model Product类的方法找到所有产品
3、在model中的Product类中写找所有产品的方法
4、修改view中的store页面
B2 增加页面layout
1、在view/layout下增加与控制器为名字的文件store.html.erb,这样,相应的控制器会默认地使用这个Layout
关于其中的一些语法标签,如stylesheet_link_tag将会使用public/stylesheet里面对应文件名的.css文件来显示
访问store页面过程:从layout中与控制器同名的store.html.erb来显示,这个文件中的yield :layout会自动替换view中产生的store内容到此处,
这种方式也可以用@content_for_layout来做,不过使用yield显得更sexy
B3 使用helper方法来格式化price
直接修改view中的代码则不是很好的选择,用helper方法的number_to_currency转换值为货币方式显示
B4 链接到cart
增加一个链接到按钮Add to Cart 到页面,使用标签Button_to标签,而不是link_to标签,因为后者发送get请求,不会做任何行动,而前者则发送post请求,并可以传递参数,由服务器相应
在修改view/store/index.html.erb后,由于按钮是一个块元素,它将显示在下一行中,我们要使它显示在Price之后,就要修改对depot.css,加入按钮显示的方式inline内嵌
Chapter 8 构建 购物车
8.1 sessions:它是类似于Hash的集合,rails用它来存储请求过程中的键值对
在数据库中放置sessions:
1、先用rake db:sessions:create创建sessions数据库的迁移,然后运行迁移:rake db:migrate
2、把config/environment.rb的"#config.action_controller.session_store = :active_record_store"的#号去掉
这样,depot应用将把session数据存到数据库中,目的是:把session数据保持到应用之外存储,以便在需要时被多个应用程序共享
sessions and Browsers
默认情况下rails实现用cookie来存储session id 在用户浏览器上。
为了防止同一个服务器上运行不同的应用,就需要用不同的cookie名来存储它们的session keys,否则可能会造成混乱
在rails命令建立应用时,它为cookie确定了一个名称,用来存储session id,这个名称包含了该应用的名称,它是通过
app/controllers/application.rb文件来完成这个过程的。我们需要插入一行来确定session id 的值,并且去掉下一行中secret的注释
现在,我们需要建立一个对购物车对象的查找,并且能把它保存在用户session中,所以建立了方法find_cart,它被建为私有,使得在类外部不可见
Task C1 建立购物车
1、建立cart.rb在app/models下,作为一个activeRecord
2、views/store/index.html.erb下加入按钮相应的action方法add_to_cart和参数id
3、控制器目录下controllers/store_controller.rb加入add_to_cart方法
4、此时需要把执行add_to_cart方法后的情况显示出来,rails会自动找views/store/add_to_cart.html.erb文件,于是我们需要建立该文件
Task C2 建立更好的购物车
1、在models下建立cart_item.rb,它作为存储购物车中的项成立,它拥有俩个属性:product和quantity
2、这样cart.rb中添加产品的方法就要改变了,先前是加入product,现在是加入CartItem,但是传入的参数均是product,只是要更新quantity的值
3、改变views/store/add_to_cart.html.erb文件的部分显示内容
问题:当我们把页面刷新时,session中存储的已经加入购物车的产品信息均会丢失,我们可以把session信息加入到数据库session表中,刷新时只要根据id查找相应的session,返回给用户即可
Task C3 处理错误
1、在我们刷新页面时,会出现类似http://localhost:3000/store/add_to_cart/4的url,4表示id,如果用户把4随便改成一个其他不存在的id,就会出现报错页面,我们修改这个错误显示,使用户不致以为是工程编写错误
2、rails定义了一个flash结构来处理错误和错误报告,它类似于一个hash表,flash的内容在这个session自动被删前的下次请求时是有用的,它特别是用来记录错误信息,在views下,利用flash的accessor方法是可以存取flash信息的
3、我们把add_to_cart方法重写,加入异常处理,(因为显示的页面就是由于该方法产生)把错误分别重定向到log文件和flash[:notice]中。
4、修改对store控制器的通用模板layouts/store.html.erb,把错误显示的方式(调用id = "notice"的css styling 显示)加在该文件中,然后加入一个显示的style,这里在public/stylesheet/depot.css中写一个id 为notice的css styling。
Task C4 完成购物车
1、增加清空购物车的按钮,首先在depot_h/app/views/store/add_to_cart.html.erb增加该按钮和相应的方法
2、在depot_h/app/controllers/store_controller.rb增加empty_cart方法
3、另一种empty_cart方法:把提示和转向放在redirect_to_index中,这样不用到flash
4、对add_to_cart方法进行升级,加入到购物车的产品能分别显示它们的价格和所有产品价格之和,这要把models中的cart类加入计算价格之和的方法
5、显示在depot_i/app/views/store/add_to_cart.html.erb里改
Task D1 移动购物车
1、partial template把它当成对views的一个方法,简称为partial,你可以通过模板或者控制器来调用一个partial
2、这里我们使用partials两次,先看看它在购物车中显示它自己
开始:1、我们的目的是把add_to_cart.html.erb(之前为)的页面显示在store。html.erb的左边sidebar上
2、修改layout/store.html.erb,在里面加入partial template,该view模板的名称为_cart.html.erb,即显示_cart.html.erb中的内容在侧边栏
3、_cart.html.erb的显示内容和add_to_cart.html.erb相同,但是其中的@cart被替换为了cart,因为@cart在store.html.erb中作为对象参数传递进来了,这里用cart与@cart传递的对象名刚好相同,即是cart类型的
4、为了保证页面其他部分显示不变,则把页面重定向到index,给用户的感觉是只加入了sidebar的内容,这样定义重定向到index以后,控制器不再转到默认的add_to_cart.html.erb,所以该页面也就没有用处了
Task D2 基于ajax的购物车
1、首先在app/views/store/index.html.erb(显示在store.html.erb的主要部分,由yield完成)下修改,加入form_remote_tag helper方法,用submit_tag来代替button_to来添加按钮“Add to Cart”
2、在app/views/layouts/store.html.erb里加入<%= javascript_include_tag :defaults %>,保证用户的浏览器能使用javascript库
3、在用户点击“add to cart”后,由store控制器的add_to_cart方法处理,前面的方法是重定向到主页,现在调用respond_to来用一个.js格式的javascript来响应,这样add_to_cart完成对ajax请求的处理
4、虽然我们完成了添加这个过程,但没有对用户显示出来,respond_to给出相应的js文件,我们通过编写add_to_cart.js.rjs这个js模板文件在views/store下,它告诉我们替换<div>的id为"cart"的内容为"cart" partial模板的内容,这个partial模板为_cart.html.erb
Task D3 高亮度改变
出现问题:没有得到预期效果
1、我们前面说过,javascriopt_include_tag helper会把许多javaScript库下到浏览器里,在javascript库中,有一个effect.js能帮助你装饰许多显示效果,其中的一个是Yellow Fade技术,它高亮显示一个元素,我们要利用它来响应当前操作在购物车里面的变化
2、我们有一个方法来标记最近改变的item,这个工作从Cart 层开始,我们让add_product返回CartItem对象
3、在store_controller.rb中调用了add_product方法,把其返回值赋给current_item,该值作为一个全局值,在 _cart_item.html.erb中增加的那一行item进行highlight
Task D4 隐藏Empty Cart:在购物车为空时,我们让它不显示出来
1、最简单的方法是<% unless cart.items.empty? %>加在_cart中硬编码;
2、1的方法虽然可以,但是它要重写侧边栏,我们用更smooth的方式来处理,使用Script.aculo.us effects库中的blind_down,它能平滑地显示购物车,直至消失
3、当我们点击EmptyCart按钮时,希望购物车不要再显示出来(因为购物车为空)。为了抽象出对view的处理,我们写一个helper模块的方法hidden_div_if,使购物车不显示出来
4、修改EmptyCart方法,由于执行controllers方法后需要重定向到一个页面,我们把它指向index
Task D5 当浏览器用户禁止使用javascript时
1、在我们使用ajax的标签 form_remote_tag以前,使用刷新的方式显示内容,如果javascript被禁,就可以用原来的方式显示页面内容
2、当我们点击form_remote_tag里的按钮时,有两种情况发生:如果javascript被禁将使用HTTP POST请求引发目标动作,它如同普通的form来工作;如果javascript可用,它将覆盖传统的POST方法,使用JavaScript对象确立与服务器的连接,这个对象是XmlHTTPRquest类的实例,简写为xhr
3、服务器接到请求在做出页面view响应前,我们只需判断请求的类型是否为xhr,如果是则可以用ajax,否则重定向到index页面
Task E Check out付账
Task E1 获取预订
1、在数据库中建立order表和line_item购物项表,ruby script/generate model order,然后在db/migrate里面写入创建表的方法
2、rake db:migrate更新数据库
3、Models之间的关系,在Order Record类和Product Record类中加入has_many,说明(1对多的关系?),在LineItem类里加入belongs_to,说明belongs_to后的类不为空,否则该类不存在。
4、创建Order获取的Form:首先加入Checkout按钮在depot_p/app/views/store/_cart.html.erb;如果购物车非空,则生成一个订单类,否则现在购物车为空;执行完该方法后,将转到对应的checkout.html.erb文件,建立这个文件。在该文件中form_for 是一个form helper方法,<% form_for
rder, :url => { :action => :save_order } do |form| %>第一个参数表示处理实例变量@oreder,url表示点击按钮后,将产生http post请求,由控制器中的save_order动作来处理
5、唯一tricky的事情是下拉列表,我们定义选项数组PAYMENT_TYPES在Order.rb中,以防忘记,二维数组的第一个元素作为下拉列表的项显示,第二个值存储在数据库中。如果我们把这个二维数组存于另一个表中,在rails下也是很方便的,只要传递给select helper 在表中find的结果就可以。
6、实现save_order动作
7、最后一点ajax的改进:在提交订单后会提示“Thank you for your order”,如果此时继续添加,这个提示不会消失,我们通过page.select("div#notice").each { |div| div.hide }来消除这个提示,它表示隐藏所有显示过#notice的div
Task F 管理
Task F1 添加用户
1、首先,使用脚手架生成一user表,相应地会产生控制器、Helper、view、与model,里面包含姓名、hashed_password,salt三个元素,salt用来与hashed_password一起生成sha1编码后的密码,它们会产生160位的hash
2、rake db:migrate
3、修改对User类里元素的验证,如非空、密码验证等过程,注意attr_accessor 类型的password_confirmation对应第二次输入的密码,它只作为一个暂存变量,不会保存在数据库中,所以在User类里面定义它
4、写产生Hash密码的方法encrpted_password和产生salt的方法,这些方法都是对外不可见的,我们在用password方法来生成hashed_password时、用authorize来验证用户身份正确性时,就要用到这两个私有方法
5、管理用户:在已经生成的用户控制器中,已有show、create、edit、destroy等方法,修改相应的代码,使得创建用户和更新用户信息后返回users的Index页面
6、最好,我们要更新用来建立新用户的form,在new.html.erb页面提交form,似乎是由create方法处理,并把它存入数据库中,但是为什么是create来处理呢?
7、然后在users的Layout代码users.html.erb中加入depot。css
Task F2 登录界面
1、我们需要一个form来填写用户名及密码;一旦登录,我们要记录其sessin,直到退出登录;控制应用的权限,仅仅允许登录用户来管理store
2、建立控制器,与三个动作login logout和index,使用命令ruby script/generate controller admin login logout index
3、修改login动作和index对应的方法和显示页面
Task F3 限制存取权限
1、我们在所有控制器的父类中加入autherize方法做权限验证,保证为登录用户不能进入系统
2、但是这个权限管得太大,store控制器也被包括进去了,我们可以在store控制器中覆盖authorize方法,来避免store也需要用户验证才能进入
3、我们保证用户在登录以后能转到它登录以前的那个页面,需要保持登录以前的uri,这就要修改authorize和Login方法来达到目的
Task F4: 侧边栏,更多的管理
1、我们在ApplicationController这个父类中加入layout "store",则可以把它所有子类的控制器对应的页面都显示store的layout;注意,为什么我们这里的users控制器没有显示这些页面呢?这是由于脚手架生成了users.html.erb在layouts中,我们删除它后即可显示出侧边栏了。
2、为防止删掉所有用户,导致不能管理,在destroy方法里加入异常
3、最好做了两件事:1、把丑陋的代码@cart=find_cart写成一个方法(我没有做这步)2、在使用find_cart前要保证为清空购物车,即:empty_cart不异常
Task G
有时候市场部人员要给已订购过书的用户发送邮件,可以通过如下方法来找到想要联系的用户,REST类型接口表示用http verbs在应用间发送请求和响应
这里的例子是找出某中产品的订单
1、建立product类和订单的一对多关系,在Product类里加入申明
2、建立控制器info与相应的动作who_bought,who_bought用来找查产品订单,authorize覆盖使得我们不用登录系统
3、写显示订单的xml文件who_bought.xml.builder与html文件who_bought.html.erb,对不同的请求用不同的文件来响应
4、产生整个工程的文档:rake doc:app,用rake stats来查看
在此,我们建立了inPlaceEditing工程,作为rails for recipes的内容
Rails in Depth
14.2 目录结构
app/和test/:大部分工作都在这两个目录中,
doc/目录存放应用程序文档,如果用doc:app命令,会生成HTML文档在doc/app目录下
lib/目录存放不能简介地放在model,view,controller下的代码,例如你写的一个用户可下载PDF收据的库,这个库直接从控制器发送到浏览器(使用send_data方法)
Tasks,这是lib/下的一个空目录,可以在此写rake tasks,例如这里我们写db_schema_migrations.rake来查看迁移的日志
script/包含一些脚本程序,如server,generate等
14.2、(中文版) ActiveRecord
model类与同名的复数数据库表相连,我们可以用ActiveRecord基类的columns()方法来得到它的属性信息
CRUD的介绍
condition、limit参数、offset参数
下部分讲控制器
Chapter 15 Active Support
Active Support是所有rails组件共享的库
15.1、一般的可用扩展,rails把ruby对象扩展了两个方法to_json和to_yaml,他们可以把对象转成JavaScript Object Notation 和YAML (the same notation used in Rails configuration and fixture files)
rails还扩展了一个blank?方法,用来判断对象是否为空,空格,fals,nil均为真
15.2、枚举和数值
groupby方法:groups = posts.group_by {|post| post.author},把author作为Key,author对应一组具有相同author值的集合
Rails扩展的另外两个方法:index_by方法是把一个集合转换成一个hash,其中的元素的key由传递进去的参数给出 state_lookup = us_states.index_by {|state| state.short_name}
sum方法是把所有的元素值传递给块,然后返回块中所有元素为一个集合total_orders = Order.find(:all).sum {|order| order.value }
15.3、字符串扩展
string = "Now is the time"
puts string.at(2) #=> "w"
puts string.from(8) #=> "he time"
puts string.to(8) #=> "Now is th"
puts string.first #=> "N"
puts string.first(3) #=> "Now"
puts string.last #=> "e"
puts string.last(4) #=> "time"
puts string.starts_with?("No") #=> true
puts string.ends_with?("ME") #=> false
count = Hash.new(0)
string.each_char {|ch| count[ch] += 1}
puts count.inspect #=> {" "=>3, "w"=>1, "m"=>1, "N"=>1, "o"=>1,
"e"=>2, "h"=>1, "s"=>1, "t"=>2, "i"=>2}
puts "cat".pluralize #=> cats
puts "cats".pluralize #=> cats
puts "erratum".pluralize #=> errata
puts "cats".singularize #=> cat
puts "errata".singularize #=> erratum
puts "first_name".humanize #=> "First name"
puts "now is the time".titleize #=> "Now Is The Time"
当单复数转换出现问题时,可以自定义于environment.rb文件的最后
15.4、对数的扩展
puts 3.ordinalize #=> "3rd"
puts 321.ordinalize #=> "321st"
puts 20.bytes #=> 20
puts 20.kilobytes #=> 20480
puts 20.megabytes #=> 20971520
puts 20.gigabytes #=> 21474836480
puts 20.terabytes #=> 21990232555520
puts 20.petabytes #=> 22517998136852480
puts 20.seconds #=> 20
puts 20.minutes #=> 1200
puts 20.hours #=> 72000
puts Time.now #=> Thu May 18 23:29:14 CDT 2006
puts 20.minutes.ago #=> Thu May 18 23:09:14 CDT 2006
15.5、时间和日期的扩展
now = Time.now
puts now #=> Thu May 18 23:36:10 CDT 2006
puts now.to_date #=> 2006-05-18
puts now.to_s #=> Thu May 18 23:36:10 CDT 2006
puts now.to_s(:short) #=> 18 May 23:36
15.6、Ruby Symbol扩展
15.7、with_options
把众多重复选项放在with_options中
15.8、Unicode 支持
Unicode有三种编码形式UTF32 UTF16 UTF8,Rails中把字符串存在Unicode中,使用utf8
Ruby库对Unicode支持不好,但是在Rails中写了一个Chars类来解决这个问题,这个类建立了和类名相同的方法,调用后会将字符串转化为Unicode编码>> name.length 与>> name.chars.length
要想保持字符编码的正确,还要保证从浏览器到数据库各个数据路径都使用相同编码,举一个Unicode Name的应用例子
分享到:
相关推荐
RoR-Depot Ruby on Rails 仓库项目
ror实例ror实例ror实例
NULL 博文链接:https://xuxiangpan888.iteye.com/blog/266696
RoR性能优化经验谈,牛人对ror的优化,值得大家阅读
ror中文资料ror中文资料
ruby on rails 留言板程序
ROR 架构介绍及了解
亲密网络 一个 ROR 应用程序 天蓝色:#20B8E8(32、184、232)地球红色:#FF6699(255、102、153)森林黑色#000033(0、0、51)
1、亮4个灯、暗4个灯,1亮1暗均匀分布,且...4、采用ROR、ROL循环移位语句(P77)及LOOP语句(P81),实现一个灯从第1个循环点亮到第8个,然后从第8个循环点亮至第1个,一直上下循环。 5、用二进制形式显示自己的学号。
此自述文件通常会记录启动和运行应用程序所需的任何步骤。 您可能想要涵盖的内容: Ruby版 系统依赖 配置 数据库创建 数据库初始化 如何运行测试套件 服务(作业队列、缓存服务器、搜索引擎等) 部署说明 … ...
基于RoR的博客系统,代码风格简单清晰,前后太完善,适合初学者。
神经网络ror resenet模型 cifar10准确率89% cifar100准确率72%
之前本人在windows 上搭建ROR环境,屡屡受挫,上网查资料、加入ruby on rails的qq群,关注ruby社区等,没有得到一套完整的正确的方法,很多朋友说不要在windows 弄ROR,很费力。的确很费力,后来在朋友的帮助下,...
RoR选题方向—源代码
此自述文件通常会记录启动和运行应用程序所需的任何步骤。 您可能想要涵盖的内容: Ruby版 系统依赖 配置 数据库创建 数据库初始化 如何运行测试套件 服务(作业队列、缓存服务器、搜索引擎等) 部署说明 … ...
家蚕Ror2基因的克隆与表达分析,刘伟,陈菲,Ror家族属于受体酪氨酸激酶中的孤儿受体,在进化上非常保守。本研究克隆了家蚕Ror2基因BmRor2的ORF序列,BmRor2基因的ORF为1924 bp,编码638
ROR环境 Ruby version 1.9.3 (java) RubyGems version 1.8.24 Rack version 1.4 Rails version 3.2.12 JavaScript Runtime therubyrhino (Rhino) Active Record version 3.2.12 Action Pack version 3.2.12 ...
该自述文件通常会记录启动和运行应用程序所需的所有步骤。 您可能要讲的内容: Ruby版本 系统依赖 配置 数据库创建 数据库初始化 如何运行测试套件 服务(作业队列,缓存服务器,搜索引擎等) 部署说明 ...
破解版本的JAR包,放到本地磁盘,ECLIPUS直接用,到JVM设置直接加 -noverify -javaagent:D:\javarebel.jar
mysqlDriver4ror.rarmysqlDriver4ror.rarmysqlDriver4ror.rarmysqlDriver4ror.rar