我是Ruby on Rails的新手,作为C#开发人员,当我想重用代码(对于一个存储库类)时,我可以把它放到类型为<T>
的基类中,以便能够做这样的事情:
public virtual IEnumerable<T> GetAll()
{
return Context<T>.GetAll();
}
如果我需要做任何自定义逻辑,我当然可以覆盖我的“用户”存储库中的方法。
在Ruby中,我很熟悉你可以这样做:
class UsersController < ApplicationController
这将允许访问ApplicationController中的所有方法及其父类。使用scaffolding时,它会在每个子类中生成以下方法:
def index
@users = User.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @users }
end
end
我最终得到的是10个具有相同方法的类,但唯一的区别是'User.all','Post.all'等。
我如何将此方法设为通用,以便将其放入ApplicationController类中?
感谢您为Ruby on Rails新手提供的任何帮助。
答案 0 :(得分:4)
首先要了解的脚手架代码是它可以被删除,因此:
def index
@users = User.all
end
除非您打算以其他格式(如json,html,pdf)提供视图,否则不需要respond_to块。如果您仍然觉得需要干掉这种方法,那么您可以执行类似
的操作# app/controllers/concerns/autoload_records.rb
module AutoloadRecords
included do
before_action :load_records, only: :index
before_action :load_record, only: [:create, :show, :edit, :update, :destroy]
end
private
def load_records
@records = model_class.all
end
def load_record
@record = model_class.find(params[:id])
end
def model_class
klass = self.class.to_s[/\A(\w+)sController\Z/,1] #=> get the name of the class from the controller Constant
Object.const_get(klass)
end
end
并像
一样编写控制器class UsersController < ApplicationController
include AutoloadRecords
def index
@records # => #<ActiveRecord::Relation[...]>
end
def show
@record # => #<User ...>
end
def non_rest_action
@record # => nil
@records # => nil
end
end
答案 1 :(得分:3)
而不是做eval
,而你真的不想做一个。查看Jose Valim的Inherited Resources宝石。它为所有控制器提供标准的CRUD方法,并且非常复杂。它也经过全面测试,因此您无需担心确保您的通用代码在所有情况下都按预期运行。
有关如何使用它的详细信息,请参阅链接的GitHub页面。
答案 2 :(得分:3)
也许一个简单的解决方案就是依赖mixins。
您定义了一个模块,
module MyModule
def my_index(klass)
@elements = klass.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @elements }
end
end
end
然后,你有你的控制器,
include MyModule
def index
my_index(User)
end
当然,您需要在视图中使用@elements。如果您想在每个视图中使用不同的变量名称
def my_index(klass, var_name)
self.instance_variable_set(var_name, klass.all)
...
end
答案 3 :(得分:1)
有几个rails插件可以帮助减少这种重复。轨道广播第230集介绍了这个。
答案 4 :(得分:0)
@user = User.all
这样的10个索引操作。如果您事先知道不同模型之间的某些操作将是相同的 - 那么提取通用逻辑可能是有意义的。但那么这些模型可能会以某种方式连接起来吗?我不会提前说Post和User会有相同的索引操作。