How I use helpers in ActionView instance? - ruby-on-rails

How I use helper methods in an ActionView instance?
I create an ActiveView object in Worker to render a layout in background.
I write a helper in helpers directory, but I can't use in layout rendered by my worker:
In app/workers/worker.rb:
av = ActionView::Base.new
av.view_paths = ActionController::Base.view_paths
# ...
av.render :template => "...", layout => "layouts/my_layout"
In app/helpers/my_helper.rb:
module MyHelper
def my_tag(param)
# do something
end
end
In app/views/layouts/my_layout.html.erb:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<%= my_tag "application" %>
</head>
<body>...</body>
</html>
It's this throw error in foreman:
ActionView::Template::Error: undefined method `my_tag' for #<ActionView::Base:0xc3da390>
System:
ruby -v: ruby 1.9.3p448,
rails -v: Rails 3.2.11

Related

Encoding iso-8859-1 isn't working on rails 5

Basically project is upgraded from ruby 1.8 to ruby 2.5.
ISO-8859-1 encoding is declared on pages which works fine in previous ruby and rails version.
Also method is written in application controller.
before_action :set_charset
def set_charset
response.headers["Content-Type"] = "text/html; charset=ISO-8859-1"
end
application layout is declared like following.
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
but in ruby 2.5 at javascript_tag it gives following error.
<%= javascript_include_tag "application" %>
Encoding::InvalidByteSequenceError
"\xA3" on UTF-8
Tried following options at rails level but it won't work.
application.rb
config.encoding = "ISO-8859-1"
config.force_encoding = "UTF-8"
Removed all old js files from application. It started running.

Rails not rendering public/index.html file; blank page in browser

I have a problem with my Rails + React app when I deploy it to Heroku. The React client is inside a client/ directory of the Rails app. Due to using react-router, the Rails server needs to know to render the index.html from the React build. When I deploy the client on Heroku, a script copies the content from client/build/. to the Rails app's public/ dir.
Now here is the problem: when my route detects a path like example.com/about it tries to render public/index.html. Here is the method:
def fallback_index_html
render file: "public/index.html"
end
However, the contents from this file are not sent to the browser. I get a blank page. I have added a puts "hit fallback_index_html" in the method and confirmed that this method is being hit. I have also opened the file in puts each line to confirm the file has the required html (this is what appeared in the logs from that puts and what SHOULD be sent to the browser):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<link rel="manifest" href="/manifest.json">
<link rel="shortcut icon" href="/favicon.ico">
<title>Simple Bubble</title>
<link href="/static/css/main.65027555.css" rel="stylesheet">
</head>
<body><noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="text/javascript" src="/static/js/main.21a8553c.js"></script>
</body>
</html>
The most recent fix I tried was going into config/environments/production.rb and changing config.public_file_server.enabled to true. This did not help.
I'm using Rails API, so my ApplicationController inherits from ActionController::API instead of ActionController::Base.
From Rails API docs it says:
The default API Controller stack includes all renderers, which means you can use render :json and brothers freely in your controllers. Keep in mind that templates are not going to be rendered, so you need to ensure your controller is calling either render or redirect_to in all actions, otherwise it will return 204 No Content.
Thus Rails API only cannot render HTML! The following allowed me to render the html without including everything from ActionController::Base.
class ApplicationController < ActionController::API
include ActionController::MimeResponds
def fallback_index_html
respond_to do |format|
format.html { render body: Rails.root.join('public/index.html').read }
end
end
end
The reason I am including ActionController::MimeResponds is to have access to the respond_to method.
My Rails application now renders index.html from my public directory when a subdirectory is hit and my React client / react-router takes over from there.

Generating a PDF with Sidekiq & Wicked PDF: Undefined local variable or method for worker#

I've been trying to get PDF's generated via sidekiq and wicked_pdf in a rails 5.1 app but keep getting this error:
2017-11-01T02:20:33.339Z 1780 TID-ovys2t32c GeneratePdfWorker JID-b3e9487113db23d65b179b1c INFO: start
2017-11-01T02:20:33.369Z 1780 TID-ovys2t32c GeneratePdfWorker JID-b3e9487113db23d65b179b1c INFO: fail: 0.03 sec
2017-11-01T02:20:33.371Z 1780 TID-ovys2t32c WARN: {"class":"GeneratePdfWorker","args":[2,1],"retry":false,"queue":"default","jid":"b3e9487113db23d65b179b1c","created_at":1509502833.334234,"enqueued_at":1509502833.3345}
2017-11-01T02:20:33.380Z 1780 TID-ovys2t32c WARN: NameError: undefined local variable or method `quote' for #<GeneratePdfWorker:0x007fb6d5cea070>
Did you mean? #quote
2017-11-01T02:20:33.380Z 1780 TID-ovys2t32c WARN: /Users/stefanbullivant/quottes/app/workers/generate_pdf_worker.rb:18:in `perform'
I get this error even with no locals being passed in the av.render method. Any ideas on what's causing it are appreciated.
quotes_controller.rb calling the worker
def create_pdf
#quote = Quote.find(params[:id])
GeneratePdfWorker.perform_async(#quote.id, current_account.id)
redirect_to #quote
end
Generate_pdf_worker.rb
class GeneratePdfWorker
include Sidekiq::Worker
sidekiq_options retry: false
def perform(quote_id, account_id)
#quote = Quote.find(quote_id)
#account = Account.find(account_id)
# create an instance of ActionView, so we can use the render method outside of a controller
av = ActionView::Base.new()
av.view_paths = ActionController::Base.view_paths
# need these in case your view constructs any links or references any helper methods.
av.class_eval do
include Rails.application.routes.url_helpers
include ApplicationHelper
end
pdf = av.render pdf: "Quote ##{ #quote.id } for #{ #quote.customer_name }",
file: "#{ Rails.root }/tmp/pdfs/quote_#{#quote.id}_#{#quote.customer_name}.pdf",
template: 'quotes/create_pdf.html.erb',
layout: 'layouts/quotes_pdf.html.erb',
disposition: 'attachment',
disable_javascript: true,
enable_plugins: false,
locals: {
quote: #quote,
account: #account
}
# pdf_html = av.render :template => "quotes/create_pdf.html.erb",
# :layout => "layouts/quotes_pdf.html.erb",
# :locals => {
# quote: #quote,
# account: #account
# }
# use wicked_pdf gem to create PDF from the doc HTML
quote_pdf = WickedPdf.new.pdf_from_string(pdf, :page_size => 'A4')
# save PDF to disk
pdf_path = Rails.root.join('tmp', "quote.pdf")
File.open(pdf_path, 'wb') do |file|
file << quote_pdf
en
end
end
quotes_pdf.html.erb PDF Layout
<!DOCTYPE html>
<html>
<head>
<title>Quottes</title>
<meta charset="utf-8" />
<meta name="ROBOTS" content="NOODP" />
<style>
<%= wicked_pdf_stylesheet_link_tag 'quote_pdf' -%>
</style>
</head>
<body>
<div class="container">
<%= yield %>
</div>
</body>
</html>
create_pdf.html.erb PDF View (for the sake of getting things running first, just two lines using each local)
<%= account.brand_name %>
<%= quote.customer_name %>
Any advice on getting this running is much appreciated. I have played around with simply generating plain html text in the pdf view without passing any variables and still get this error so I'm confused as to what's causing it.
I sometimes forget about this as well - It seems like it's very insistent that line 18 (which I can only assume is render) is looking up the quote local and can't find it, and #quote is defined at that time. If that is all your code, then I would presume the changes are not being picked up.
My best suggestion (which I hope works) is you need to restart sidekiq!

Using asset pipeline outside of ERB

Is there a way to use the rails asset pipeline outside of erg? When I call stylesheet_link_tag(), I get a normal /stylesheets/ link instead of an /assets/ like I'd expect. I suspect that the stache gem just needs to register something with the asset pipeline, but I'm not sure what.
I'm using this gem: https://github.com/agoragames/stache
The code I'm using:
module Layouts
class Application < ::Stache::View
include ActionView::Helpers::AssetTagHelper::StylesheetTagHelpers
def title
'foobar'
end
def stylesheets
[
[stylesheet_link_tag('reset', :media => 'all')]
]
end
def javascripts
end
end
end
It's generating:
<link href="/stylesheets/reset.css" media="all" rel="stylesheet" type="text/css" />
It should be generating (it does this in erb templates):
<link href="/assets/reset.css?body=1" media="all" rel="stylesheet" type="text/css" />
Using rails 3.2.3.
Try
def stylesheets
[
[stylesheet_link_tag("#{ActionController::Base.helpers.asset_path('reset.css')}", :media => 'all')]
]
end
also read https://stackoverflow.com/a/9341764/643500
The proper solution is to remove the:
include ActionView::Helpers::AssetTagHelper::StylesheetTagHelpers
line at the top.

How to send mail in HTML format in Rails 2.3.11?

I've only found solutions that work in Rails 3, so far. How can I force emails sent with ActionMailer to be formatted as HTML, rather than plaintext?
/app/models/franklin.rb (the mailer)
class Franklin < ActionMailer::Base
def activation(user)
recipients user.email
from "activation#rit.oncampusapp.net"
content_type = "text/html"
subject "OnCampus # RIT Registration"
body :user => user
end
end
/app/views/franklin/activation.html.erb
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
</head>
<body>
Hi <%= #user.full_name %>,
This is your activation email for OnCampus # RIT. All you have to do is click the link below, and you'll be able to log in.
<%= link_to "Activate My Account!", "http://rit.oncampusapp.net/admin/activate?key=#{#user.activation_key}"%>
We hope to see you soon! :D
-- The OnCampus Team
</body>
</html>
Have you tried setting in the activation action content_type "text/html" instead of content_type = "text/html"
Just paste this in your notifier/mailer model method - this will solve your problem
content_type "text/html"

Resources