简略的说,redirect_to是执行页面的跳转,发送请求重定向页面,执行对应的action,重新加载服务器数据,不保留页面原有数据;
render是简单的页面渲染,可以指定渲染页面和布局文件,不会发送请求,不会执行action函数,不会重新加载服务器数据。
这里举个例子说明一下:
users_controller.rb:
def create_login_session
user = User.find_by_name(params[:name])
if user && user.authenticate(params[:password])
cookies.permanent[:token] = user.token
redirect_to :admin_welcome
else
flash[:error] = "用户名不存在或密码错误"
redirect_to :login
end
end
login.html.rb:
<div class="center-block" id="login">
<h3>登录</h3>
<div class="">
<%= form_tag "/create_login_session" do %>
<dl class="input-group">
<dt class="input-group-addon">
<%= label_tag "帐号" %>
</dt>
<dd class = "">
<%= text_field_tag :name, params[:name], :class => "form-control" %>
</dd>
</dl>
<dl class="input-group">
<dt class="input-group-addon">
<%= label_tag "密码" %>
</dt>
<dd class = "">
<%= password_field_tag :password, params[:password], :class => "form-control" %>
</dd>
</dl>
<% if flash[:error] %>
<div class = "alert alert-danger">
<%= flash[:error] %>
</div>
<% end %>
<p> <%= submit_tag "登录", :class => "btn-default btn btm-primary" %> </p>
<% end %>
</div>
</div>
当在登录页面输入帐号密码后点击登录,如果帐号密码不匹配,这时调用create_login_session方法就会显示flash的错误到页面,而输入的帐号和密码将会被清空,因为redirect_to重新发送了请求,重新加载了登录页面,重新获取了服务器的数据。如果这是点击浏览器的刷新按钮,也就相当于重新再执行了一次redirect_to,这时flash的内容在登录页面上也会消失,因为flash的内容缓存已经清空了。
如果将redirect_to改为render:
render :login
这时登录输入不正确点击登录,输入的帐号和密码的内容将还会在页面上显示,显示flash的错误到页面,此时刷新相当于render,内容一直存在页面,因为render不会发送请求,不会重新加载服务器数据,它只是渲染了页面。
接下来通过另一个例子深入了解一下render和redirect_to:
test_controller.rb:
def test1
puts "test1_one"
render :test1
puts "test_wo"
end
def test2
puts "test2_one"
redirect_to :test2
puts "test2_two"
end
在对应的views文件夹下有test1.html.rb和test2.html.rb
在浏览器中,test1页面显示:
test1_one
test1_two
test2页面会显示:
test2_one
test2_two
test2_one
test2_two
........
这里总结一下这个例子,在执行render或redirect_to前,def中的所有代码都会按照顺序执行一遍,比如test1页面显示了test1_two;render是渲染页面,不会发送请求,不会重新加载服务器的数据;而redirect_to是跳转到一个页面,而例子会一直循环跳转到当前页面,加载数据,导致死循环。