0

バックボーン アプリの :json で current_user のすべての機能を受け取る必要があります。したがって、最初のアイデアは、次のような考えを追加することでした。

def receive_user_abilities # we will return onty hash for works and tasks
    w = Work.accessible_by(current_ability).map { |w| w = {type: 'Work', id: w.id}) }
    t = Task.accessible_by(current_ability).map { |t| t = {type: 'Task', id: t.id}) }
    render json:  t + w # returs merged hash
end

しかし、どちらの行も同じなので、メタプログラミングの魔法を使うことにしました。したがって、私の解決策は、新しいヘルパーを作成し、それをコントローラーに含め、*arg を新しく作成したモジュール (ヘルパー) メソッドに渡すことでした。ここにあります:

 module AbilitiesHelper
  def receive_abilities_for *classes
    classes.inject([]) { |res, klass| res + eval( klass.to_s.capitalize + '.accessible_by(current_ability).map { |element| element = ({type: ' + klass.to_s.capitalize + ', id: element.id }) }') }
  end
end

ここにコントローラーからの新しい呼び出しがあります

def receive_user_abilities
    render json: receive_abilities_for(:work, :task) # returs merged hash
  end

基本的には同じなのですが、なぜかエラーが出ますSystemStackError - stack level too deep:

エラーはどこですか??

4

1 に答える 1

1

たぶん、このアプローチはより簡単でしょうか?

def receive_abilities_for *classes
  classes.inject([]) do |res, klass| 
    res + klass.accessible_by(current_ability).map do |element| 
      element = {type: klass.to_s, id: element.id } 
    end
  end
end

そして、このメソッドを次のように呼び出します。

def receive_user_abilities
  render json: receive_abilities_for(Work, Task)
end

また、私はreceive_abilities_forメソッドはメタプログラミングではありません。メタプログラミングとは、実行時に新しいメソッドとクラスを定義することです (私は間違っているかもしれません)。

于 2013-08-29T10:06:28.030 に答える