原創,轉載請注明http://www.cnblogs.com/juandx/p/3963023.html
rails中path、url路徑解析,routes信息,form_for剖析,link_to示例
1、首先要了解routes中resources的member、collection、new的關系 =>
http://www.cnblogs.com/juandx/articles/3962694.html
2、然后在cmd中rake routes要看懂
C:\Users\Administrator\Desktop\lianxizhong\lianxi1_form_for\depot>bundle exec ra ke routes orders_index GET /orders/index(.:format) orders#index xshow_order GET /orders/:id/xshow(.:format) orders#xshow xcreate_orders POST /orders/xcreate(.:format) orders#xcreate orders GET /orders(.:format) orders#index POST /orders(.:format) orders#create new_order GET /orders/new(.:format) orders#new edit_order GET /orders/:id/edit(.:format) orders#edit order GET /orders/:id(.:format) orders#show PUT /orders/:id(.:format) orders#update DELETE /orders/:id(.:format) orders#destroy
第一列指路徑名稱,比如第二個xshow_order 這樣就可以引用xshow_order_path 和 xshow_order_url 了,不然當你隨便亂用_path和_url的時候就會提示
undefined local variable or method `xcreate_orderss_path' for #<#<Class:0x42d8600>:0x3791190>
第二列是對應的http verb選項
第三列是對應路徑
第四列是對應控制器和其中的方法,比如orders#xshow中就是這個路徑要對應到orderscontroller 中的 xshow方法
3、實例解釋
先看一下代碼
orderscontroller.rb
class OrdersController < ApplicationController def index flash.now[:notice] = 'Message sent!' @order = Order.all end def new @order12 = Order.new end def create flash.now[:notice] = "bb" @order = Order.new(params[:order]) if @order.save flash[:notice] = "yes" redirect_to :action => 'index' else flash.now[:alert] = "no" end end def xcreate flash.now[:notice] = "bb" @order = Order.new(params[:order]) if @order.save flash[:notice] = "yes" redirect_to :action => 'index' else flash.now[:alert] = "no" end end def show @order = Order.find(params[:id]) end def xshow @order = Order.find(params[:id]) end end
routes.rb
Depot::Application.routes.draw do get "orders/index" resources :orders do get 'xshow', on: :member post 'xcreate', on: :collection end end
index.html.erb
<h1>hello,rails </h1> <% @order.each do |oo| %> <div> <%= oo.name %> <%= link_to 'see', xshow_order_path(oo) %><br/> <%= sanitize(oo.des) %> </div> <% end %> <br/> <br/> <%= link_to "create" , new_order_path %>
new.html.erb
<%= form_for @order12 , url: xcreate_orderss_path do |f| %> <div> <%= f.label "Name is" %><br /> <%= f.text_field :name, :size => 40 %> </div> <div> <%= f.label :Description %><br /> <%= f.text_area :des, :rows => 3, :cols => 40 %> </div> <div> <%= f.submit 'Place Order' %> </div> <% end %>
show.html.erb
<p> <b>Name:</b> <%=h @order.name %> </p> <p> <b>Description:</b> <%= @order.des %> </p> <%= link_to 'Back', orders_path %>
好了,最后的show和xshow是一樣的,create和xcreate是一樣的,目的就是想學習下路由而已
注意了,
(1)、先看看form_for的構造吧:
在controller中new方法中@order12 = Order.new,這樣就會把一個實例傳給new.html.erb中的那個表單,這樣表單就能根據@order12中的屬性來構造:
比如<%= f.text_field :name, :size => 40 %>中的name就是@order12中的name屬性,必須一一對應。
然后在表單中填完數據后要發送給一個地址,然后執行post請求,所以在表單第一行就寫好了<%= form_for @order12 , url: xcreate_orders_path do |f| %>
說明寫完數據后,最后submit是到xcreate_order_path的路徑,看看那個cmd中的路由就知道是到了orderscontroller中的xcreate方法。所以如果不用path寫法也可以直接寫成
<%= form_for @order12 , url: {:action => "xcreate"} do |f| %>。這樣之后就可以直接讓xcreate中執行post請求了(就是 @order.save)。在controller中的xcreate方法中 的@order = Order.new(params[:order]),就是因為new.html.erb中最后submit后的是一個params[:order],而不是剛剛的@order12了,這里寫成不同就是為了區別。
其實默認的是new.html.erb之后直接對應到controller中的create,后台代碼我還沒讀,但是,默認的url是到create的,所以你什么都不寫的話,如<%= form_for @order12 do |f| %>,然后在controller中的create中用 @order.save就可以保存信息到數據庫里了,所以我這里為了驗證就新建了一個xcreate方法了。
(2)、link_to
在index.html.erb中,可以看到<%= oo.name %> <%= link_to 'see', xshow_order_path(oo) %><br/>,這樣就建了一個連接,因為在routes中用 的是member方法,所以這樣就可以傳遞參數進去了。當然,如果什么path都不寫,一開始的話是默認到show的。。。這應該也是rails后台默認的吧。。。所以在web敏捷開發里就是這 樣<%= oo.name %> <%= link_to 'show', oo %><br/>了。。。
當然不用path寫法也可以直接寫,但是要對應好rake routes中的路由路徑信息 比如路徑信息是 xshow_order GET /orders/:id/xshow(.:format) orders#xshow,那么就要 這樣寫:<%= link_to 'see', {:controller => "orders",:id => oo, :action => "xshow"} %>
4、對routes中的resources寫法補充
Example::Application.routes.draw do resources :vmc_vstores resources :vdisks do get 'download', on: :member end resources :vstores do member do get 'volumn_vdisk_info' post 'do_unmount_cdrom_vdisk' end get 'topo', on: :collection end namespace :admins do resources :users do get 'lock', on: :member get 'unlock', on: :member end resources :roles match ':controller(/:action(/:id))(.:format)' end