2017-01-20 33 views
0

ユーザーのための通知を生成するカスタムクラスを作成したいと思います。私の質問は、link_to経由で通知テキストのリソースへのリンクを生成する方法です。ActionController :: Base以外のクラスにActionView :: Helpersを正しく組み込む方法は?

私はalreay試した何

:I create_text方法で表示されますMakerクラスにActionView::Helpers::UrlHelperRails.application.routes.url_helpersを含め、エラーをfollwing持っていた、:

thisから続く命令と「どのようにモデルにlink_toを使用する」のような同様の答えをlink_toを使用しよう:

EmployeesControllerTest#test_company_vacancy_daily: 
NameError: undefined local variable or method `controller' for #<Notifies::Maker:0x000000069ae218> 
    /usr/local/rvm/gems/ruby-2.2.5/gems/actionview-5.0.0.1/lib/action_view/routing_url_for.rb:132:in `optimize_routes_generation?' 
    /usr/local/rvm/gems/ruby-2.2.5/gems/actionpack-5.0.0.1/lib/action_dispatch/routing/route_set.rb:192:in `optimize_routes_generation?' 
    /usr/local/rvm/gems/ruby-2.2.5/gems/actionpack-5.0.0.1/lib/action_dispatch/routing/route_set.rb:172:in `call' 
    /usr/local/rvm/gems/ruby-2.2.5/gems/actionpack-5.0.0.1/lib/action_dispatch/routing/route_set.rb:295:in `block (2 levels) in define_url_helper' 
    /usr/local/rvm/gems/ruby-2.2.5/gems/actionpack-5.0.0.1/lib/action_dispatch/routing/polymorphic_routes.rb:262:in `handle_model_call' 
    /usr/local/rvm/gems/ruby-2.2.5/gems/actionview-5.0.0.1/lib/action_view/routing_url_for.rb:116:in `url_for' 
    /usr/local/rvm/gems/ruby-2.2.5/gems/actionview-5.0.0.1/lib/action_view/helpers/url_helper.rb:196:in `link_to' 
    /app/lib/notifies.rb:32:in `block in create_text' 
    /app/lib/notifies.rb:32:in `map!' 
    /app/lib/notifies.rb:32:in `create_text' 
    /app/lib/notifies.rb:38:in `run' 
    /app/test/controllers/notifications_test.rb:167:in `block (2 levels) in <class:EmployeesControllerTest>' 
    /usr/local/rvm/gems/ruby-2.2.5/gems/activesupport-5.0.0.1/lib/active_support/testing/assertions.rb:71:in `assert_difference' 
    /app/test/controllers/notifications_test.rb:166:in `block in <class:EmployeesControllerTest>' 

そして、私のコードは次のとおりです。

module Notifies 
    class Maker 

    include ActionView::Helpers::UrlHelper 
    include Rails.application.routes.url_helpers 

    def initialize(model, kind) 
     @model = model 
     @kind = kind 

     case @model.class.to_s 
     when 'Company' 
     @to = @model.admin 
     when 'Employee' 
     @to = @model 
     end 
    end 

    def build_list 
     present = Time.now.utc 
     past = present - 24.hours 

     popularities = Popularity.where(to: @model.entity.id).select do |e| 
     e.updated_at.utc.between?(past, present) 
     end 

     popularities.map! { |p| p.from_entity.turn } 
    end 

    def create_text(popularities = build_list) 
     text = 'Those users interested in your contacts: ' 
     popularities.map! { |p| link_to p.full_name, p } 
     text + popularities.join(', ') 
    end 

    def run 
     popularities = build_list 
     text = create_text(popularities) 
     @to.notify(kind: @kind, text: text) if popularities.any? 
    end 
    end 
end 

答えて

1

私はこれを行う方法を理解しました。エラーが間違ってurl_for呼び出しによって引き起こされた、そしてそれは、パラメータonly_pathと呼ばれるべきなので、同じよう:

def create_text(popularities = build_list) 
    text = 'Those users interested in your contacts: ' 
    popularities.map! do |reciever| 
    link_to reciever.full_name, url_for([reciever, only_path: true]) 
    end 
    text + popularities.join(', ') 
end 

または代替としてdefault_hostパラメータはenviropment設定ファイルで設定する必要があります。

0

プレゼンターパターンのバリエーションを使用することをお勧めします(これは、プレインの古いRubyオブジェクトでlink_toのようなメソッドを呼び出すことができます)。 Ryan Batesさんは、このトピックでは良いRailsCastを持っています。ここでは...私はそれを行うだろうか大体だ

まず、私は(私は私のappディレクトリにpresentersフォルダを保つ)PresenterBaseクラスを作成したい:私はcontrollerに渡す

app/presenters/presenter_base.rb 

    class PresenterBase 

    class << self 
     def present(controller)  new(controller).present     end 
    end 

     def initialize(controller) @controller = controller    end 

    private 

     def controller()   @controller        end 
     def view_context()   controller.view_context     end 

     def get_controller_variable(sym) 
     controller.instance_variable_get("@#{sym}") 
     end 

     def method_missing(*args, &block) 
     view_context.send(*args, &block) 
     end 

    end 

お知らせcontroller.view_contextview_contextにアクセスしてください。次にmethod_missingを無効にして、link_toメソッドを持つview_contextに未知のメソッド(link_toなど)を送信します。

次に、あなたのNotifies::Makerはこのようになります:

class Notifies::Maker < PresenterBase 

    class << self 
     def run(controller) new(controller).run end 
    end 

     def run 
     to_notify.notify(kind: kind, text: text) if popularities.any? 
     end 

    private 

     def kind()   @kind ||= get_controller_variable(:kind)  end 
     def model()   @model ||= get_controller_variable(:model) end 
     def past_time()  present_time - 24.hours      end 
     def popularities() @popularities ||= get_popularities   end 
     def present_time() @present_time ||= Time.now.utc    end 

     def to_notify() 
     case model.class.to_s 
     when 'Company' 
      model.admin 
     when 'Employee' 
      model 
     end 
     end 

     def get_popularities 
     Popularity.where(to: model.entity.id).select do |e| 
      e.updated_at.utc.between?(past_time, present_time) 
     end 
     end 

     def text 
     'Those users interested in your contacts: ' << links 
     end 

     def links 
     popularities. 
      map!{ |p| p.from_entity.turn }. 
      map!{ |p| link_to p.full_name, p }. 
      join(', ') 
     end 

    end 

最後に、あなたのコントローラは、このようなものになります。

class FooController < ApplicationController 

    def foo_method 
     @model = some_method_to_set_model 
     @kind = some_method_to_set_kind 
     Notifies::Maker.run(self) 
    end 

    end 

を私がテストしていないので、それはバグがある可能性があります。しかし、おそらくそれが役に立ちます。

+1

ありがとうございますが、これはリンクが付いた1行のテキストのみを生成するには複雑すぎるようですので、私はいくつかの調査を行い、答えを見つけました。 – Max

関連する問題