`
backsnow
  • 浏览: 127589 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

第一个RoR程序depot建立过程

    博客分类:
  • RoR
阅读更多
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_forrder, :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-Depot Ruby on Rails 仓库项目

    ror实例

    ror实例ror实例ror实例

    ror

    NULL 博文链接:https://xuxiangpan888.iteye.com/blog/266696

    RoR性能优化经验谈

    RoR性能优化经验谈,牛人对ror的优化,值得大家阅读

    ror中文资料

    ror中文资料ror中文资料

    ror留言板程序

    ruby on rails 留言板程序

    初探ROR

    ROR 架构介绍及了解

    intimate_web:一个 ROR 应用程序

    亲密网络 一个 ROR 应用程序 天蓝色:#20B8E8(32、184、232)地球红色:#FF6699(255、102、153)森林黑色#000033(0、0、51)

    实验1 简单IO应用—流水灯控制

    1、亮4个灯、暗4个灯,1亮1暗均匀分布,且...4、采用ROR、ROL循环移位语句(P77)及LOOP语句(P81),实现一个灯从第1个循环点亮到第8个,然后从第8个循环点亮至第1个,一直上下循环。 5、用二进制形式显示自己的学号。

    Shopify:这是我本地的 RoR 应用程序

    此自述文件通常会记录启动和运行应用程序所需的任何步骤。 您可能想要涵盖的内容: Ruby版 系统依赖 配置 数据库创建 数据库初始化 如何运行测试套件 服务(作业队列、缓存服务器、搜索引擎等) 部署说明 … ...

    RoRBlog 基于RoR的博客系统

    基于RoR的博客系统,代码风格简单清晰,前后太完善,适合初学者。

    神经网络ror resenet模型

    神经网络ror resenet模型 cifar10准确率89% cifar100准确率72%

    Windows 上搭建 ROR环境

    之前本人在windows 上搭建ROR环境,屡屡受挫,上网查资料、加入ruby on rails的qq群,关注ruby社区等,没有得到一套完整的正确的方法,很多朋友说不要在windows 弄ROR,很费力。的确很费力,后来在朋友的帮助下,...

    RoR选题方向—源代码

    RoR选题方向—源代码

    firstapp:我的第一个 ROR 应用程序

    此自述文件通常会记录启动和运行应用程序所需的任何步骤。 您可能想要涵盖的内容: Ruby版 系统依赖 配置 数据库创建 数据库初始化 如何运行测试套件 服务(作业队列、缓存服务器、搜索引擎等) 部署说明 … ...

    家蚕Ror2基因的克隆与表达分析

    家蚕Ror2基因的克隆与表达分析,刘伟,陈菲,Ror家族属于受体酪氨酸激酶中的孤儿受体,在进化上非常保守。本研究克隆了家蚕Ror2基因BmRor2的ORF序列,BmRor2基因的ORF为1924 bp,编码638

    ROR绿色最新环境(2013/3/10)

    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 ...

    mi_primer_rails_app:Odin的第一个RoR应用程序

    该自述文件通常会记录启动和运行应用程序所需的所有步骤。 您可能要讲的内容: Ruby版本 系统依赖 配置 数据库创建 数据库初始化 如何运行测试套件 服务(作业队列,缓存服务器,搜索引擎等) 部署说明 ...

    javarebel 用JAVA和ROR一样方便测试

    破解版本的JAR包,放到本地磁盘,ECLIPUS直接用,到JVM设置直接加 -noverify -javaagent:D:\javarebel.jar

    mysqlDriver4ror.rar

    mysqlDriver4ror.rarmysqlDriver4ror.rarmysqlDriver4ror.rarmysqlDriver4ror.rar

Global site tag (gtag.js) - Google Analytics