红宝石中的模块与关注 - 干

时间:2012-08-09 00:54:39

标签: ruby-on-rails ruby module dry

我在我的Rails项目中有一个名为Activities的控制器,其中包含此模块'Sortable':

控制器:

class ActivitiesController < ApplicationController

  include Sortable
  ...

模块(工作):

module Sortable
  def save_positions
    @ids = params[:ids]
    # ~ Converting to array separating by ',' 
    @ids = @ids.split(",")

    count = 0
    # ~ Saving new positions
    for i in @ids
      Activity.update(i, {:position => count})
      count += 1
    end

    render :json => :success
  end
end

但是当我重构代码时,我可以和其他控制器一起使用:

EDITED

require 'active_support/concern'

module Sortable
  extend ActiveSupport::Concern

  module InstanceMethods
    def save_positions
      @ids = params[:ids]
      # ~ Converting to array separating by ',' 
      @ids = @ids.split(",")

      count = 0
      # ~ Saving new positions
      for i in @ids
        update(i, {:position => count})
        count += 1
      end

      render :json => :success
    end
  end
end

我做错了什么?

新错误消息:

ArgumentError (wrong number of arguments (2 for 0)): app/controllers/activities_controller.rb:61:in 

我从

中删除了“活动”
Activity.update(i, {:position => count}) 

1 个答案:

答案 0 :(得分:2)

控制器操作在控制器上实现为实例方法,而不是类方法。除了你已经将save_positions定义为类方法而不是实例方法这一事实之外,你已经从我所看到的一切中完美地设置了所有东西。

require 'active_support/concern'

module Sortable
  extend ActiveSupport::Concern

  module InstanceMethods ## <== just changed this
    def save_positions
      ...
    end
  end
end

更新以回答问题的下一部分:

您正尝试从共享控制器操作调用模型上的方法。你无法提前知道那个模型是什么。如果确实希望将代码保存在控制器而不是模型中,我们可以在运行时找出模型并使其工作

共享的save_positions操作:

def save_positions
  @ids = params[:ids]
  # ~ Converting to array separating by ',' 
  @ids = @ids.split(",")

  count = 0
  # ~ Saving new positions
  for i in @ids
    AR_CLASS.update(i, {:position => count})
    count += 1
  end

  render :json => :success
end

一些随机控制器:

class ActivitiesController < ApplicationController
  include Sortable
  AR_CLASS = Activity
  # ....
end

class FoosController < ApplicationController
  include Sortable
  AR_CLASS = Foo
  # ....
end

然后,您的save_postition操作会在正确的模型上调用update,具体取决于它运行的控制器。