2012-05-04 15 views
8

動的アクティブ管理スコープに問題があります。私は自分のアプリで "プロジェクト"の各 "マネージャ"のスコープを作成しようとしています。ただし、スコープは、新しいマネージャーが作成されたとき(またはプロジェクトに割り当てられたとき)は更新されないようですが、サーバーを再始動すると更新されます。したがって、コード自体は「機能する」ものですが、明らかに私が望むやり方ではありません。私はルビー/レールnoobだから私は何かを "リフレッシュする"ために何かをする必要があるかどうかわからない。ちなみに、私はここで 関連するモデルの各インスタンスのアクティブな管理スコープ

ActiveAdmin

でHerokuの杉上のRails 3.2を使用していますよう

は、問題のコード(サーバーが再起動された後でのみ動作新しい経営者にもたらします)です:


Manager.find_each do |m| 
    scope m.first_name do |projects| 
    projects.where(:manager_id => m.id) 
    end 
end 

全体のActive管理プロジェクトモデル:

ActiveAdmin.register Project do 
menu :priority => 1 
index do 
    column :name 
    column :company_name 
    column :status 
    column :projection do |project| 
    number_to_currency project.projection 
    end 
    column :updated_at 
    default_actions 
end 

scope :all 
scope :working, :default => true do |projects| 
    projects.where(:status => 'working') 
end 

Manager.find_each do |m| 
    scope m.first_name do |projects| 
    projects.where(:manager_id => m.id) 
    end 
end 
end 
+0

悪い得ることができます。なぜ私はそれを答えたものにしなかったのか分かりません。 –

答えて

1

Railsのが唯一のクラスをロードします生産モードではつまり、スコープは一度呼び出されてからキャッシュされます。これは、新しいスコープが再起動後まで表示されない理由です。あなたの場合にマネージャー名を編集しても同じことが起こります。

私は解決策がラムダまたはProcを使用するかもしれないと思っていますが、数分で私はそれと一緒に遊んだので、私は成功しませんでした。 activeadminの書き方も可能ではないかもしれません。

+0

できないことは間違いありません。 activeadminが有効なレコードスコープメソッドの周りにスコープラッパーを実装したことで、これは禁止されています。おそらく、 "reload_scope"メソッドは、save/commitフックの後に何とかactiverecordに公開される可能性があります。それをどうやって行うのか考えてみませんか? –

2

AAレジスタブロック内の真のダイナミックスコープは機能しません。これで、Managerテーブルの変更が、初期化時に作成された動的スコープに反映されないことを意味します。また、https://github.com/gregbell/active_admin/wiki/Creating-dynamic-scopesを参照してください。あなたが試みることができるのは、スコープの代わりにフィルターを使用することです。

filter :managers, :as => :select, :collection => proc { Manager.order('name ASC').map(&:first_name) } 

と管理職の特性の変化が表示されます(ページの更新後の)サーバーを再起動せず:次に、あなたのような何かを書くことができます。また、チェックしてください https://github.com/gregbell/active_admin/issues/1261#issuecomment-5296549

アクティブなレコードスコープは異なる!アクティブな管理者スコープからのあなたは、私が私のために働くためにこれを見つけた

http://apidock.com/rails/ActiveRecord/NamedScope/ClassMethods/scope

+1

ありがとう! procでコレクションをカプセル化することは、オンデマンドで実行できるように正しく行われます。これは 'rake db:schema:load'と' rake db:migrate'の問題も解決します。 ActiveAdminフィルターは、プロシージャーで囲まれていない場合、作成される前にスキーマにアクセスしようとします。 – scarver2

3

確認する必要があります

ActiveAdminファイル

scope :working, :default => true do |projects| 
    Project.working 
end 

モデル

scope :working, -> { where(:status => 'working') } 

ビット返事が遅れでなく、うまくいけばそれは誰かを助ける。

+2

これは実際に複数のスコープを作成するために機能しましたか? 1つのスコープが作成されていることがわかります。 – James

10

この問題の実際の解決策です。代わりにフィルタを使用すると、より望ましい安定性と保守性が得られます。これはActiveAdminでよりよく見え、スコープは見栄えの良いタブになるのでユーザーフレンドリです。

それはハックのビットですが、それは適切な実行可能なソリューションです:

トリックは更新コントローラのindexアクションにbefore_filterでスコープにあります。(あなたは簡単にいくつかの制限を設定することができますaltho)あなたは、リソース上で作成された多くのスコープを持っている場合

これは、次の答えは素晴らしいです

ActiveAdmin.register Project do 
    menu :priority => 1 
    index do 
    column :name 
    column :company_name 
    column :status 
    column :projection do |project| 
     number_to_currency project.projection 
    end 
    column :updated_at 
    default_actions 
    end 

    scope :all 
    scope :working, :default => true do |projects| 
    projects.where(:status => 'working') 
    end 

    controller do 
    before_filter :update_scopes, :only => :index 

    def update_scopes 
     resource = active_admin_config 

     Manager.all.each do |m| 
     next if resource.scopes.any? { |scope| scope.name == m.first_name } 
     resource.scopes << (ActiveAdmin::Scope.new m.first_name do |projects| 
      projects.where(:manager_id => m.id) 
     end) 
     end 

     # try something like this for deletions (untested) 
     resource.scopes.delete_if do |scope| 
     !(Manager.all.any? { |m| scope.name == m.first_name } || ['all', 'working'].include?(scope.name)) # don't delete other scopes you have defined 
     end 

    end 
    end 
end 
+0

Githubのおかげでいくつかの推奨事項がありました: [関連GitHubの問題](https://github.com/gregbell/active_admin/issues/1261#issuecomment-22207740) –

+0

それらが削除されたときについて? –

+1

私はそれをテストするためのセットアップではありませんが、私は削除に役立ついくつかのコードを追加しました。 –

関連する問題