我有车型:
路线:
map.resources :vehicles, :has_many => :suppliers
一切都很好,但是Vehicle有一个布尔属性 is_truck 。我想做一个Alias所以我可以获得相同的资源只过滤卡车,我试过:
路线:
map.trucks '/trucks', :controller => :vehicles, :action => :index, :is_truck => true
map.trucks '/trucks/by_supplier/:supplier', :controller => :vehicles, :action => :index, :is_truck => true
第一个效果很好,但是当我在表单中搜索时,第二个不起作用并搜索所有供应商。
控制器:
class VehiclesController
def index
if params[:supplier]
@vehicles = Vehicle.all :conditions => { :is_truck => params[:is_truck] }
else
@vehicles = Vehicle.all
end
end
...
end
搜索表单
<% form_for :truck, :url => {:controller => :trucks, :action => :index}, :html => {:method => :get} do |f| %>
<% f.text_field :search %>
<% f.submit 'Search Trucks' %>
<% end %>
是否可以 map.resources 作为别名?
答案 0 :(得分:1)
我找到了一种更干净的方法,但在某个特定供应商下搜索仍然无法:
# Show all vehicles
map.connect '/vehicles/supplier/:supplier', :controller => :vehicles, :action => :index
map.resources :vehicles
# Only show trucks
map.connect '/trucks/supplier/:supplier', :controller => :vehicles, :action => :index, :is_truck => true
map.resources :vehicles, :as => 'trucks', :requirements => { :is_truck => true }
资源:http://api.rubyonrails.org/classes/ActionController/Resources.html
答案 1 :(得分:1)
只需按以下方式修改路线:
map.resources :vehicles, :has_many => :suppliers,
:collection => { :trucks => :get }
并检查rake routes
生成的路线。它将允许您列出卡车的车辆:
trucks_vehicles GET /vehicles/trucks(.:format)
{:controller=>"vehicles", :action=>"trucks"}
所以你现在只需要添加一个名为“truck”的新动作,其作用类似于“index”。如果您创建卡车或其他车辆,表格应该自己跟踪(通过表单字段)。不要尝试使用rails路由,这通常意味着您的应用程序设计存在缺陷,这会让您以后遇到麻烦。
您可以查看STI(单表继承:一个表存储多个类别的车辆)。另一种方法是创建一个卡车控制器,它继承了车辆控制器并覆盖了一些类似的方法:
class TrucksController < VehiclesController
def new
@is_truck = true
super
end
...
end
或
class TrucksController < VehiclesController
before_filter :this_is_a_truck
...
private
def this_is_a_truck
@is_truck = true
super
end
end
更新:这是另一个(假设您有一个is_truck列):
class TrucksController < VehiclesController
around_filter :with_truck_scope
...
private
# Scope every active record access with an is_truck condition
# you may want to put this directly into the model to get rid of the .send
# method and directly access "Vehicle.with_truck_scope &block" here
def with_truck_scope(&block)
Vehicle.send :with_scope, :find => { :conditions => "is_truck = 1" },
:create => { :is_truck => 1 }, &block
end
end
但我建议首先尝试使用Rails路由的:collection
和:member
参数。
答案 2 :(得分:0)
你在控制器中处理它吗?
像往常一样:class VehiclesController
def index
if params[:supplier]
@vehicles = Vehicle.all :conditions => { :supplier_id => params[:supplier] }
else
@vehicles = Vehicle.all
end
end
end
答案 3 :(得分:0)
不确定是否可以制作别名,但至少可以尝试交换路线:
map.trucks '/trucks/by_supplier/:supplier', :controller => :vehicles, :action => :index, :is_truck => true
map.trucks '/trucks', :controller => :vehicles, :action => :index, :is_truck => true
由于路线的工作方式类似于“首次添加 - 具有更高的优先级”,因此您的解决方案可能会失败,因为map.trucks'/ truck'也会捕获'/ trucks / by_supplier /:supplier'。我也建议稍微重构一下:
map.with_options :controller => :vehicles, :action => :index, :is_truck => true do |v|
v.trucks '/trucks/by_supplier/:supplier'
v.trucks '/trucks'
end
答案 4 :(得分:0)
我建议您使用其他资源,只需添加:
map.resources :vehicles, :as => :trucks, :has_many => :suppliers
然后在控制器中处理它,例如:
def index
conds = {}
conds = { ... } if request.uri =~ /trucks/ # you can be more specific about the regexp if you need to
@vehicles = Vehicle.all :conditions => conds
end
你怎么看?