2013-08-15 28 views
23

Tôi đã đọc rất nhiều về cách render các partials Rails và các khung nhìn trong các nhiệm vụ/công việc/mô hình rake. Phần lớn những thứ tôi đã tìm thấy trên Stackoverflow và web mô tả các cách tiếp cận làm việc trong Rails 3, nhưng chúng dường như đã lỗi thời và tôi không làm cho chúng hoạt động (thậm chí với một số thời gian thử nghiệm).Hiển thị partials/view trong một công việc/công việc trên nền/rake trong Rails 4

Vì vậy, làm thế nào tôi có thể hiển thị một phần trong công việc nền trong Rails 4?

Đây là cách tiếp cận tốt nhất mà tôi đã làm việc cho đến nay (được trình bày trong bảng điều khiển).

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' 

Bất kỳ ý tưởng nào? Cảm ơn trước!

Cập nhật: Số tweet_path được đề cập ở trên thực sự không được xác định. Lỗi này phát sinh từ việc liên kết tới đường dẫn = link_to 'Tweet', [@project, tweet] (mẫu mỏng) bằng cách sử dụng một biến mẫu sẽ có mặt trong các lượt xem kế thừa từ một bộ điều khiển nhất định, nhưng không xuất hiện khi được hiển thị bên ngoài ngữ cảnh này. Tôi đã giải quyết vấn đề này thông qua hiệp hội thích hợp thay vì = link_to 'Tweet', [tweet.project, tweet].

Trả lời

33

Dưới đây là những gì tôi tổng hợp từ nhiều nguồn khác nhau và những gì làm việc cho tôi trong Rails 4.

Với lớp Renderer này, bạn sẽ có thể để render Rails 4 lượt xem và partials trong bất kỳ bối cảnh, như công việc nền, đối tượng dịch vụ, mô hình, công nhân, bạn tên nó.

# 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 

Cập nhật:

Có vẻ là một giải pháp dễ dàng hơn: 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. 

Cập nhật 2:

Có một viên ngọc gọi render_anywhere cho phép gọi " hiển thị "từ mọi nơi: mô hình, công việc nền s, nhiệm vụ cào vv

Cập nhật 3:

Trong Rails 5, các renderer đã được chiết xuất và có thể được sử dụng độc lập từ việc nền và những nơi khác:

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

Đối với Rails < = 4.2, chức năng này có thể được backported với backport_new_renderer gem.

+0

" Giải pháp dễ dàng hơn "hoạt động nhưng không cung cấp quyền truy cập vào các chức năng như" link_to "thường được sử dụng trong mẫu. Không có giải pháp nào dường như cung cấp quyền truy cập cho người trợ giúp ứng dụng cụ thể. –

+0

@JeremyBurton Bạn có thể cung cấp cho ['render_anywhere'] (https://github.com/yappbox/render_anywhere) một thử và xem liệu người trợ giúp có thể được đưa vào đó không. –

+0

Tôi thực sự giải quyết vấn đề bằng cách đơn giản bao gồm các mô-đun trợ giúp tôi cần trong lớp ViewRenderer. Cảm ơn. –

3

Đảm bảo bạn đang tải môi trường đường ray trong công việc. Nếu điều đó đã được thực hiện bạn có thể thử một cái gì đó như:

include Rails.application.routes.url_helpers 
+0

Đối với người trợ giúp URL động cơ, đó là 'MyEngine :: Engine.app.url_helpers' (ray 4) – Jay

Các vấn đề liên quan