Rails一天搞定 1.0

在这里,我们用最基本的方式告诉大家如何使用Rails开发,通过这些内容,足够开发一个普通的网站,因为使用最基本的方式,所以难免达到最佳实现,甚至会比较丑陋,但是,这无疑是最低成本的学习。阅读本文需要一定的基础,比如如何使用generate script 身成model,controller等

 

1.必须明白的几件事情

1)任何一个action对应一个同名字的template,这个action中的instance variables在template中可见(其他地方均不可见)

2)我们认为任何controllers,views目录下的class和template可见models目录下的class,或者说,action pack component可以使用active records component 提供的class(我们这里先不谈layout)

 

2.从 Active Records Component 说起,解决对单张表的维护

操控数据要依靠active records component,我们关心的是model目录,ActiveRecord::Base class提供了对数据库存取的支持(注意是存取支持),我们说过model的作用是用来存取数据和约束数据,因此程序员要做的就是在model目录下面的class中填充约束数据的代码以及有关的存取操作(建立在存取支持的基础上)

 

简单的例子:

我们建立了一个关于友情链接的表

create table links(
    id int not null auto_increment,
    web varchar(100) not null,
    link varchar(100) not null,
    primary key(id)
);

 

注意表中必须有一个名字为 id 的主键,并且设置为auto_increment

如何操作其数据?

1)建立有关的model

>ruby script/generate model link

 

2)建立有关的controller

>ruby script/generate controller main

 

3)从数据库中读取数据

ActiveRecord::Base class提供了对数据库存取的支持,model下面的类都是继承于ActiveRecord::Base的,所以我们建立的link class就有了一些可用的method,最重要的就是find

前面说过,我们认为models目录下的class在controllers下是可见的,也就是这样做是合法的

class MainController < ApplicationController

  def index
    @links = Link.find_all         # 使用ActiveRecord::Base中的find_all方法
  end
end

 

find method 介绍:

find method可以说是最重要的方法之一了

 

可以通过3种从数据库取回数据的方式使用find:

a.通过每个表中的 id 的值进行检索(因为每个表都有id列),例如:

find(1)            # 读取 id=1 的行

find(1,4,9)      # 读取 id=1,4,9 的行

这种方式,如果只有一个id,返回这个行对应的object,如果有多个ids,返回一个数组包含这些object

 

b.使用first,取回第一条数据

find(:first)       # 读取第一条数据

这种方式,返回一个对应行的object

 

c.使用all,取回所有数据

find(:all)          # 取回所有数据,相当于find_all

这种方式,返回一个数组,如果没有找到返回一个空数组[]

 

使用option hash,最后一个参数可以使用一个option hash,options有:

:conditions   表示sql语句中where子句后面的条件部分

:order 表示sql语句中order by子句后面的部分

:limit 表示取回行的数量

:offset 设定偏移量

:select 设定sql语句中select a,b,c form ... 中的abc部分
options不仅仅是这几个,还有几个比较大家可以参考Rails API,下面细细说明:

find(:all,:conditions=>"id < 5")     #注意第一个argument不能少,而option hash只是可选的

find(:all,:limit => 5,:conditions =>"id <100")  #limit限制,读取仅仅只有5行

find(:all,:select => "id,link")   #指定表中列名

find(:all,:select => "link",:order => "id desc")   #使用id降序排列

 

以上的options可以任意组合,不分顺序

 

4)显示数据库中的数据到template

前面定义了一个action index,何如在index.rhtml中显示出来?如下:

(请确保表links中有数据)

<% @links.each do |row| %>

<%=h(row.web)%>

<% end %>

前面讨论过h method,这里就不说了。之所以上面的代码可以运行,是因为action中的instance variables共享给了对应的template。

运行结果:

 

5)保存数据到数据库

一个重要的method:save,save是ActiveRecord::Base 中的一个method,因此在所有子类中,我们都可以获得save这个method

一类重要的method:每个表对应一个class,这个class将含有存取数据库中列的method,method名字与列名相同
下面是一个简单的例子:

class Link < ActiveRecord::Base
  def Link.add_link(web,link)
    rows = Link.new         # 产生一个对象new不带arguments
    rows.web = web         # 与表中的列同名
    rows.link = link            # 与表中的列同名
    rows.save                   # save用于保存数据
  end
end

 

class MainController < ApplicationController
  def index
    @links = Link.find_all

    Link.add_link("Google","http://www.google.com")
  end
end

运行http://localhost:3000/main 后,数据库会增加一笔数据:

a.理解 ActiveRecord::Base

model中继承来自 ActiveRecord::Base 的类,可以实现对列的存取操作,如何理解?通过new方法,生成的object包含2个实例变量:@new_record 和 @attributes ,@new_record用来判断是新插入的行,还是进行update,@attributes用来保存列值。

 

print Link.new.inspect

结果:

#<link:0x39949c4 @new_record="true," @attributes="{&quot;link&quot;=">"", "web"=>""}>

 

class Link < ActiveRecord::Base
  def Link.add_link(web,link)
    rows = Link.new
    rows.web = web
    rows.link = link
    rows
  end
end

 

print Link.add_link("Google","http://www.google.com").inspect

结果:

#<link:0x385d100 @new_record="true," @attributes="{&quot;link&lt;font" color="#000000">"=>"http://www.google.com", "web"=>"Google"}

 

由此我们知道,前面的rows.web,rows.link,web 和 link 只是 Virtual Attributes。所有的列值到@attributes,以待save或者读取。

 

 

b.关于new

new可以不带arguments,这时候@attributes中所有列对应一个空字符串

new也可以带一个argument,这个argument要求是一个hash object,key是列名(即可以是String literal 也可以是 symbol literal)(补充:注意这里也可以使用params[:key] 来实现 update_attributes(params[:key])的功能)

new创建的对象 @new_record = true

 

c.关于save

save会根据@new_record来进行判断,是建立一行,还是update,假如存在@new_record就建立一个新行,假如不存在就进行update操作。注意save不带parameter

d.关于update

本来是可以通过save来进行update操作的,不过它有时候不是最好的选择,比如我们现在可以得到一个hash表,进行update就很简单了,可以通过 update_attributes(hash object) 完成,这个method是很有用的,我们会结合表单提交部分做些实例

 

3.表单提交

表单有最重要的3部分

1)开始:<%= start_form_tag(:action => "action_name") %>

2)提交按钮:<%= submit_tag("submit") %>

3)结束:<%= end_form_tag %>

 

注意template中使用的是helper methods

上图完整的显示了如何进行一个重要的操作---update。这里面涉及到了参数的传递问题,这里要强调的隐含含义:

params是Hash的子类(HashWithIndifferentAccess)我们知道这一点就足够了,因为我们有一个重要的问题将设计到它。

params的argument---symbol object有特殊的含义,params保存input标签中处理过的name-value,具体是这样的:

对于形如:的input标签,params将有一个对应的key--- :test,这个key对应的value是一个hash object,也就是{:a=>"it is a", :b=>"it is b"},也就是保存了一个name-value对

 

总结来说就是:params可以保存一个name-vlaue对,这个name-value对来源与特定的标签格式,这样的格式要求name=xxx[aaa],params把xxx作为一个key(类型是symbol object),值是所有符合格式的name-value对组合而成的hash object

 

之后我们可以使用前面说过的 update_attributes method进行update操作,虽然我们完全可以不使用这样的方式,而使用极其原始的方式即并不约束input name,这样我们就必须在action中对表中的每一个列,写上一句代码,比如 Link.link = params[:input_name]

 

实例:做一个对Links表进行update的

class MainController < ApplicationController
  def edit

  #这里提一下,URL映射是这样的 http://app_name/controller_name/action_name/id ,所以这里要获取一个id

  #所以我们传递参数的时候,没有类似 ?id=1 这样的参数
    @link = Link.find(params[:id])   
  end
  def update
    link = Link.find(params[:id])
    link.update_attributes(params[:link])
    redirect_to :action => "edit", :id =>params[:id]
  end
end

 

下面是template:

<html>
    <head></head>
    <body>
        <%=start_form_tag :action=>"update"%>
        Web名称
        %=@link.web%>"/><p< font="">>
        Web地址
        %=@link.link%>"/><p< font="">>
        %=@link.id%>"/>
       
        <%=end_form_tag%>
    </body>
</html>

 

 

我们注意一下%=@link.id%>"/>这行,目的是为了传递本次修改的行的id到 update action 中,Rails提供更好的办法做这个事情:

<%=start_form_tag :action=>"update", :id=>@link.id%> 也可以写成这样:<%=start_form_tag :action=>"update", :id=>@link%>

其实更多的helper methods帮我们完成了input标签,submit标签等,但是我个人觉得,这样做把程序员和设计师的工作混合在一起了,有时候并不是一个很好的选择

 

还要说明一下的是 redirect_to method,它是ActionController::Base中的方法,是一个十分有用的方法:

redirect_to method

redirect_to(options={},*parameters_for_method_reference)

options:

1)hash,例如:

redirect_to(:controller => 'posts', :action => 'show', :id => 10)

浏览器就跳转到 http://app_name/posts/show/10

2)链接,例如:

redirect_to("http://www.i170.com/user/killercat")  #外部链接

redirect_to("/images/rails.png")   #内部链接

redirect_to("/controller_name/action_name/id_name")  #实现上面url_for的功能

3):back 返回前一个页面

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值