提前为长篇文章道歉。我已经在 Ruby on Rails 中工作了大约 6 个月,并且发现自己正在尝试将 java/C# 中的设计模式应用于 RoR 中的问题。我觉得在 RoR 中有更好的方法可以做同样的事情,但遗憾的是我只是一个菜鸟。所以这里是一个基本问题,我试图找到一个面向 Ruby 的设计模式。任何指导将不胜感激。
在我的应用程序的 Controller 中,有很多“共享”行为。在许多情况下,存在特定于 Controller 的初始化(即,将对象的 user_id 属性设置为当前用户,过滤掉一次性写入属性)并根据对象实例和当前用户授权操作。因此,许多模型和 Controller 看起来与此类似:
class Object < ActiveRecord::Base
...
def authorize_action(user, action)
[:show,:create].include?(action) || self.created_by_user_id == user.id # only the user who created can update/delete
end
def init_new(signed_in_user)
self.created_by_user_id = signed_in_user.id
if self.location_id.nil?
self.location_id = signed_in_user.default_location_id
end
end
end
ObjectController < ApplicationController
before_action :set_object, only: [:show, :edit, :update, :destroy]
before_action :authorize_action, only: [:show, :edit, :update, :destroy]
...
def new
@object = Object.new
@object.parent_id = params[:parent_id] # nested resource, assign parent_id from request url
@object.created_by_user_id = current_user.id
end
def edit
end
def create
@object = Object.new(object_create_params)
@object.parent_id = params[:parent_id] # nested resource, assign parent_id from request url
@object.created_by_user_id = current_user.id
@object.save
end
def update
@hunting_plot_user_access.update(object_update_params)
end
def destroy
@object.destroy
end
private
set_object
@object = Object.find(params[:id])
end
def object_create_params
params.require(:object).permit(:location_id, :attribute_1, :attribute_2)
end
def object_update_params
params.require(:object).permit(:attribute_1, :attribute_2)
end
def authorize_action
raise Exceptions::NotAuthorized unless @object.authorize_action?(current_user, action_name)
end
end
我想将每个常见操作的一般“流程”移动到共享逻辑中。例如,要创建任何给定对象的新实例, Controller 应该创建实例,调用实例上的 init_new 方法(所有模型都有此方法),可能应用特定于 Controller 的更改,授权操作并保存对象实例。
我认为这是一个相当普遍的设计问题。我一直在考虑使用向 ApplicationController 类添加“虚拟”方法和自定义回调的组合的解决方案,但感觉就像我在尝试将方形钉子装入圆孔中。
有人有任何可能解决相同问题的建议文章、博客文章等吗?
最佳答案
继承是一种方式:
class BaseController < ApplicationController
before_filter :some_common_thing
def some_common_thing
# common code
end
end
class ObjectController < BaseController
# just the code that is unique to this controller
end
...请注意不要走得太远 - 这是一篇关于 inheritance in ruby 的好文章(尽管它适用于任何 OO 语言)
关于ruby-on-rails - ruby on rails 设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25203978/