不知道,如果我认为这是一种最佳实践或令人厌恶的做法,但这是我在解决相同问题时想出的。
我的理由是,该网站提供了一些特定的功能(这对于本次讨论并不重要)+ 一堆关于组织本身的信息(关于我们、联系方式、常见问题解答、主页简介等)。由于所有这些数据确实与组织相关,因此将这些事物中的每一个都作为属性的组织模型似乎是合理的。这是模型:
class Organisation < ActiveRecord::Base
...validations stuff...
def self.attrs_regex
Regexp.new(self.attrs.join("|"))
end
def self.attrs
self.column_names.reject{|name| name =~ /id|created_at|updated_at/}
end
end
然后我使用 attrs 类方法根据列生成路由。这是在我的 routes.rb 中:
Organisation.attrs.each do |attr|
get "#{attr}" => "organisation##{attr}", :as => attr.to_sym
get "#{attr}/edit" => "organisation#edit", :as => "#{attr}_edit".to_sym, :defaults => { :attribute => attr }
post "#{attr}" => "organisation#update", :as => :organisation_update, :defaults => { :attribute => attr}, :constraints => Organisation.attrs_regex
end
控制器有点奇怪,我对这里的代码并不感到兴奋,但无论如何它都在这里。我需要确保属性已设置并可用于视图,以便我可以在那里做正确的事情,所以我在应用程序控制器中设置它:
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :set_attribute
def set_attribute
@attribute = action_name.parameterize
end
end
对于组织控制器,我只是在 before_filter 中将@organisation 变量设置为数据库中的第一行也是唯一的行,然后让 Rails 执行其通常的魔法调用方法、失败和呈现同名视图。编辑操作只使用一个视图文件来编辑所有不同的属性:
class OrganisationController < ApplicationController
before_filter :set_organisation
def edit
authorize! :edit, @organisation
@attribute = params[:attribute].parameterize
end
def update
authorize! :update, @organisation
@attribute = params[:attribute]
respond_to do |format|
if @organisation.update_attributes(params[:organisation])
format.html do
redirect_to "/#{@attribute}", notice: t('successful_update')
end
format.json { head :ok }
else
format.html { render action: "edit" }
end
end
end
private
def set_organisation
@organisation = Organisation.first
end
end
所以这就是我结束的地方。像你一样,我找到了 SO 以利用这里沸腾的天才,但结果令人失望。如果那里有更好的东西,我仍然希望找到它。
我喜欢我所做的是路由是根据组织表的结构自动生成的。
我不喜欢我所做的是根据组织表的结构自动生成路由。
我知道当我必须处理 i18n 路由时,我会为这个设计决定付出代价,而且可能还有一千个其他原因表明这是一个我尚未发现的坏主意,但目前我有一个满意的客户。
最后,这不是建议你应该这样做,但我希望给你比我得到的更多,这样你就可以推进你的想法,并希望最终更接近最佳实践。