2013-08-15 27 views
23

Bir komisyon görevi/arka plan işi/modeli için kısmi görünüm/görünüm oluşturma Rails kısmi ve komisyon görevleri/arka plan işleri/modellerinde görünümleri oluşturma konusunda çok şey okudum. Stackoverflow ve web üzerinde bulduğum şeylerin büyük bir çoğunluğu Rails 3'te çalışan yaklaşımları anlatıyor, ancak modası geçmiş gibi görünüyorlar ve onları çalışmalarına bile getiremedim (oldukça fazla zaman harcayarak).Rails 4

Peki, , Rails 4'teki bir arka plan işinde kısmi nasıl işleyebilirim?

Şimdiye kadar çalıştığım en iyi yaklaşım şöyledir (konsolda gösterilmiştir).

c = ApplicationController.new 
result = c.render_to_string(partial: 'tweets/tweet', locals: {tweet: Tweet.first}) 
# => 
# Tweet Load (0.8ms) SELECT "tweets".* FROM "tweets" ORDER BY "tweets"."id" ASC LIMIT 1 
# Author Load (0.6ms) SELECT "authors".* FROM "authors" WHERE "authors"."id" = $1 ORDER BY "authors"."id" ASC LIMIT 1 [["id", 1]] 
# Status Load (0.6ms) SELECT "statuses".* FROM "statuses" WHERE "statuses"."twitter_id" = 367523226848866304 LIMIT 1 
# Rendered tweets/_tweet_body.html.slim (17.5ms) 
# Rendered tweets/_resolved_tweet.html.slim (23.7ms) 
# Rendered tweets/_tweet.html.slim (28.1ms) 
# ActionView::Template::Error: undefined method `tweet_path' for #<#<Class:0x007fb21bf797a0>:0x007fb21cb009e8> 
# from /Users/thomasklemm/.rbenv/versions/2.0.0-p195/lib/ruby/gems/2.0.0/gems/actionpack-4.0.0/lib/action_dispatch/routing/polymorphic_routes.rb:129:in `polymorphic_url' 

Herhangi bir fikir? Şimdiden teşekkürler!

Güncelleştirme: Yukarıda belirtilen tweet_path gerçekten tanımlanmamıştır. Bu hata, = link_to 'Tweet', [@project, tweet] yoluna (ince şablonlar), belirli bir denetleyiciden miras alınan görünümlerde bulunacak bir örnek değişkeni kullanarak bağlantı oluşturmasıyla sonuçlandı, ancak bu bağlamın dışında oluşturulduğunda değil. Bunun yerine, = link_to 'Tweet', [tweet.project, tweet] yerine uygun ilişkiyi çözdüm.

cevap

33

Ben kaynaklardan çok sayıda derlenen Neyin Bu Renderer sınıfıyla Raylar 4.

yılında benim için çalışıyor, oluşturulması gerekir Arka plan işleri, hizmet nesneleri, modeller, işçiler gibi, herhangi bir bağlamda 4 görünüm ve kısmi raylar.

# app/services/renderer.rb 
# Render views and partials in rake tasks, 
# background workers, service objects and more 
# 
# Use: 
# 
# class MyService 
# def render_stuff 
#  result = renderer.render(partial: 'tweets/tweet', locals: {tweet: Tweet.first}) 
#  # or even 
#  result = renderer.render(Tweet.first) 
# end 
# 
# private 
# 
# def renderer 
#  @renderer ||= Renderer.new.renderer 
# end 
# end 
# 
class Renderer 
    def renderer 
    controller = ApplicationController.new 
    controller.request = ActionDispatch::TestRequest.new 
    ViewRenderer.new(Rails.root.join('app', 'views'), {}, controller) 
    end 
end 

# app/services/view_renderer.rb 
# A helper class for Renderer 
class ViewRenderer < ActionView::Base 
    include Rails.application.routes.url_helpers 
    include ApplicationHelper 

    def default_url_options 
    {host: Rails.application.routes.default_url_options[:host]} 
    end 
end 

Güncelleme: "

çağırma imkanı sağlar render_anywhere adında bir mücevher var: http://makandracards.com/makandra/17751-render-a-view-from-a-model-in-rails

ApplicationController.new.render_to_string(
    :template => 'users/index', 
    :locals => { :@users => @users } 
) 
# Mind the weird syntax to set @ variables in :locals. 

Güncelleme 2:

daha kolay bir çözüm gibi görünüyor "her yerden" render: modeller, arka plan işi vb s, tırmık görevler,

Güncelleme 3:

raylar 5, oluşturucu ekstre edilmiş ve arka plan işler ve diğer yerlerden başına kullanılabilir:

ApplicationController.renderer.render(
    partial: 'messages/message', 
    locals: { message: message } 
) 

Rails < = 4.2 için, bu işlev backport_new_renderer gem ile geri yüklenebilir.

+0

"Daha kolay çözüm" çalışır ancak şablonlarda yaygın olarak kullanılan "link_to" gibi işlevlere erişim sağlamamaktadır. Her iki çözüm de uygulamaya özel yardımcılara erişim sağlıyor. –

+0

@JeremyBurton ['render_anywhere']' i (https://github.com/yappbox/render_anywhere) deneyebilir ve orada yardımcıların bulunup bulunmayacağını görebilirsiniz. –

+0

Aslında sorunu, ViewRenderer sınıfında ihtiyaç duyduğum yardımcı modülleri içererek çözdüm. Teşekkürler. –

3

Rayların çevresine iş yüklediğinizden emin olun. zaten yapılırsa gibi bir şey deneyebilirsiniz:

İşte
include Rails.application.routes.url_helpers 
+0

Motor URL yardımcıları için, bu 'MyEngine :: Engine.app.url_helpers' (raylar 4) – Jay