ruby-on-rails - ruby on rails 设计模式

标签 ruby-on-rails ruby design-patterns

提前为长篇文章道歉。我已经在 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/

相关文章:

ruby-on-rails - https ://rubygems. 组织/不是 URI

ruby-on-rails - 如何为登录编写 Omniauth RSpec?

ruby-on-rails - rails : difference between attr_accessor and attr_accessible

c# - LINQ 依赖计算赋值

ruby-on-rails - 如何运行 Ruby 项目

ruby - 如何在我的 .rb 文件中共享变量?

ruby-on-rails - 如何解决rails 4中未初始化的常量用户

java - 转换实现相同接口(interface)的类的快速方法

javascript - 非常简单的事件驱动 jQuery 插件设计模式

ruby-on-rails - rails : Single table inheritance and find(:all) in parent