4.Action交换数据,实现提示功能
一个现实的问题,actions之间如何进行数据交换?我们知道,每次request进来,都会为其生成一个对应的controller object,这使得在controller的层面进行 actions间的数据交换变得几乎不可能,一个很简单的例子:
class MainController < ApplicationController
@@info = "no info"
def sender
@@info = "我发送了一条信息"
end
def getter
@get_it = @@info
end
end
getter.rhtml:
我收到信息:<%=@get_it%>
结果:
还好Rails为我们提供的解决办法:Flash—Communicating between Actions,看看一个例子:
修改以前的update:
def update
link = Link.find(params[:id])
if link.update_attributes(params[:link])
flash[:good] = "update succeed"
else
flash[:good] = "update falled"
end
redirect_to(:action=>"edit",:id=>params[:id])
end
在edit.rthml后面加上
运行,结果如下:
是不是使用起来很简单,下面做一下介绍:
flash ojbect,来源于ActionController::Flash::FlashHash,继承于Hash,理解这点是非常重要的,为了说明问题,还是先介绍一下Hash的特点,这里用一段代码来说明(详细参考本blog教材《http://www.i170.com/user/killercat/Article_31741》)
hash = Hash.new
hash[:hi]=1 # 添加一个element
hash[:p]=2
puts hash.inspect
^Z
{:p=>2, :hi=>1}
现在可以理解flash object了。最初的flash object是一个空的,flash[:good] = 'update succeed' 为flash添加了一个element,因此,我们还可以使用很多key-value来满足所有的action间的通讯,注意,更加确切的说,flash在整个action pack中共享,在template中,它写成@flash[key],在action中写成 flash[key]。有了flash我们就可以进行很多有意义的操作,但是更多应用中,喜欢用js来实现
5.session问题
没有session的web就无法区分使用者的角色,因此session是一个非常重要的。为了解释session的使用,先构建一个用户表:
create table users ( id int not null auto_increment, primary key(id)
insert into users(user,password) values |
>ruby script/generate model user
在main controller中添加action
def login
unless request.get? #判断时候有请求
user = User.find(:all,:conditions=>"user='"+params[:user]+"'")
if user.empty?
render_text "此用户不存在"
elsif user[0].password == params[:password]
render_text "登录成功"
session[:user] = user.id
else
render_text "密码错误"
end
end
end
编写login.rhtml
<%= start_form_tag :action=>"login" %>
name:<input name = "user" type = "text"><p>
pswd:<input name = "password" type = "text"><p>
<input type = "submit" value = "登陆">
<%= end_form_tag %>
运行如下:
登录测试:
输入 kc 123 显示 "登录成功"
输入 kc 223 显示 "密码错误"
输入 kc2 123 显示 "此用户不存在"
session和flash很像,可以认为他们都是Hash(其实不是),flash object 被action pack共享(在active record component中不可见),同时在用户的层面上,flash object是被单个用户使用的,session也是,也就是说不同的用户来看flash或者session object是不同的,它们很相似,区别在于:
session中的对象的生命周期是整个会话(关闭浏览器为结束)
flash中的对象的生命周期是下一个action结束,用于向下一个action传递信息
所以我们常用flash做错误提示
建立 before_filter 限制页面被访问:
class ApplicationController < ActionController::Base
before_filter :code
def code
@headers["Content-Type"] = "text/html;charset=gbk"
end
def authorize
unless session[:user]
redirect_to(:controller => "main", :action => "login")
end
end
end
这里建立了一个method authorize,用来判断session是否存在,假如登录以后session[:user]!=nil,这时redirect_to就不被运行,我们现在要做的就是在必要的controller中加上:
before_filter :authorize,:except=>:login #except 表示login action 不受限制
假如掌握上面提到的内容,就可以使用Rails进行一般网站的开发了,但是为了更好的满足需要,下面的内容也不可以少
6.多表的维护是个问题
一对多关系:比如books和categories
1)在books表中加上一个字段:category_id
2)修改model
class Book < ActiveRecord::Base
belongs_to :category
end
class Category < ActiveRecord::Base
has_many :books
end
想知道它属于的类别名,我就可以使用代码 @book.category.name,@category.books
其实我们完全可以通过find等method的组合实现这些方法,当然这些方法带来很大的便利,更多的情况,这里就不说了。
7.分页是个问题
action:
def action_name
@pages, @records = paginate :table_name, :per_page => 10
end
rhtml:
<% for element in @records %>
......
<%= if @pages.current.previous
link_to("Previous page", :page => @pages.current.previous )
end
%>
<%= if @pages.current.next
link_to("Next page", :page => @pages.current.next )
end
%>
8.图片上传是个问题
请参考 《Rails上传文件》