但是,当我尝试使用link_to“stuff”时,instance_of_child会收到有关无法找到正确页面的投诉.
我试过搞乱匹配’/ subclass’=>重定向(‘/ parent’),但会产生奇怪的链接,没有任何意义.有什么建议?我对rails非常陌生,我承认我对routes.rb的理解仍然有限 – 但是,我并不完全确定这是我应该在哪里看的.
解决方法
If you’ve ever tried to add STI to an
existing Rails application you
probably know that many of your
link_to and form_for methods throw
errors when you add a parent class.
This is because ActionPack looks at
the class of an object to determine
its path and URL,and you haven’t
mapped routes for your new subclasses.
You can add the routes like so,though
I don’t recommend it:
# NOT recommended: map.resources :cars,:as => :vehicles,:controller => :vehicles map.resources :trucks,:controller => :vehicles map.resources :motorcycles,:controller => :vehicles
This only alleviates a particular
symptom. If we use form_for,our form
fields will still not have the names
we expect (eg: params[:car][:color]
instead of params[:vehicle][:color]).
Instead,we should attack the root of
the problem by implementing the
model_name method in our parent class.
I haven’t seen any documentation for
this technique,so this is very
unofficial,but it makes sense and it
works perfectly for me in Rails 2.3
and 3:
def self.inherited(child) child.instance_eval do def model_name Vehicle.model_name end end super end
This probably looks confusing,so let
me explain:When you call a URL-generating method
(eg: link_to(“car”,car)),ActionPack
calls model_name on the class of the
given object (here car). This returns
a special type of string that
determines what the object is called
in URLs. All we’re doing here is
overriding the model_name method for
subclasses of Vehicle so ActionPack
will see Car,Truck,and Motorcycle
subclasses as belonging to the parent
class (Vehicle),and thus use the
parent class’s named routes
(VehiclesController) wherever URLs are
generated. This is all assuming you’re
using Rails resource-style (RESTful)
URLs. (If you’re not,please do.)To investigate the model_name invocation yourself,see the Rails source code for the ActionController::RecordIdentifier#model_name_from_record_or_class method. In Rails 2.3 the special string is an instance of ActiveSupport::ModelName,in Rails 3 it’s an ActiveModel::Name