1

私の Rails プロジェクトには、Activity という名前のコントローラーがあり、このモジュール '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

しかし、コードをリファクタリングすると、他のコントローラーで使用できます。

編集済み

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}) 
4

1 に答える 1

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

于 2012-08-09T01:42:26.787 に答える