Vanity not using Redis to Go server on Heroku - heroku

I've recently deployed some A/B testing experiments using vanity to my heroku instance. However, whenever I access the dashboard i.e. /vanity The following error shows up in the logs
- ActionView::Template::Error (Connection refused - Unable to connect to Redis on 127.0.0.1:6379):
- 1: <ul class="experiments">
- 2: <% experiments.sort_by { |id, experiment| experiment.created_at }.reverse.each do |id, experiment| %>
- 3: <li class="experiment <%= experiment.type %>" id="experiment_<%=vanity_h id.to_s %>">
- 4: <%= render :file => Vanity.template("_experiment"), :locals => { :id => id, :experiment => experiment } %>
- 5: </li>
-
However, the redis to go url seems to be set up correctly and vanity seems to be able to access it
e.g.
irb(main):011:0> Vanity.playground.connection
=> redis://bluegill.redistogo.com:9231/0
Anyone know what I could be doing wrong ?
my vanity.rb config file is fairly standard
development:
adapter: redis
connection: redis://localhost:6379/0
qa:
adapter: redis
connection: <%= ENV["REDISTOGO_URL"] %>
staging:
adapter: redis
connection: <%= ENV["REDISTOGO_URL"] %>
production:
adapter: redis
connection: <%= ENV["REDISTOGO_URL"] %>
and also the ENV["REDISTOGO_URL"] seems correct
irb(main):012:0> ENV["REDISTOGO_URL"]
=> "redis://redistogo:e1ab3fa23beacbcd481cd4508ad0090c#bluegill.redistogo.com:9231/"
And I can access Redis from the rest of the app, it just seems that Vanity is not picking it up for this template..

Ok, I've figured this one out. When we fork with unicorn I wasn't reconnecting to the correct redis server and instead defaulting to the localhost. This code snippet in unicorn.rb sorts it out.
after_fork do |server, worker|
# the following is *required* for Rails + "preload_app true",
ActiveRecord::Base.establish_connection
Vanity.playground.establish_connection(ENV["REDISTOGO_URL"])
end
I'm sure its similar for other forking servers too.

Related

Rails 5.2 ActionMailer Mail won't send. Can't see any error in server

Trying to send a volunteering form through SMTP using Gmail, Sendgrid or anything really however I have Action Mailer all set up and I presume I should really be seeing the email come through when I look at the email. I can see this error below but cannot see any error or receive any email at all. I've tried writing puts in my create action but I do not see those either so this is hopefully an easy fix as I'm missing something or have something not follow the usual Rails convention.
I'm using rails 5.2
What I see in the server:
Started GET "/volunteer?utf8=%E2%9C%93&authenticity_token=AZ%2FAflVf%2BlqRUYm45Jo82wAMpq%2B%2BY%2F93piLbeRXdK5n%2FQIWhuaUL3Oe2%2FSwzR%2FCLvj%2FAKW%2BBgD8dPd8vJYRDBA%3D%3D&volunteer_message%5Bname%5D=test+name&volunteer_message%5Bemail%5D=email%40test.com&volunteer_message%5Bphone_number%5D=88888888&volunteer_message%5Bbody%5D=test+email&commit=Send" for 127.0.0.1 at 2018-10-10 17:29:42 +0100
Processing by PagesController#volunteer as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"AZ/AflVf+lqRUYm45Jo82wAMpq++Y/93piLbeRXdK5n/QIWhuaUL3Oe2/SwzR/CLvj/AKW+BgD8dPd8vJYRDBA==", "volunteer_message"=>{"name"=>"test name", "email"=>"email#test.com", "phone_number"=>"88888888", "body"=>"test email"}, "commit"=>"Send"}
Ok so here's my code and the way it's all layed out.
PagesController.rb contains a page called volunteer and this contains the partial (Called _new.html.erb) which is the form which is in it's own folder called volunteer_messages
views/volunteer_messages/_new.html.erb
<%= simple_form_for #volunteer_message, url: create_volunteer_message_url do |f| %>
<%= #volunteer_message.errors.full_messages.join(', ') %>
<%= f.input :name, placeholder: 'name' %>
<%= f.input :email, placeholder: 'email' %>
<%= f.input :phone_number, placeholder: 'phone number' %>
<%= f.input :body, placeholder: 'body' %>
<%= f.submit 'Send' %>
<% end %>
routes created
# is this causing a problem do you think?
get '/volunteer' => 'pages#volunteer'
# volunteer message routes
get '/volunteer', to: 'volunteer_message#new', as: 'new_volunteer_message'
post '/volunteer', to: 'volunteer_message#create', as: 'create_volunteer_message'
models/volunteer_message.rb
class VolunteerMessage
include ActiveModel::Model
attr_accessor :name, :email, :phone_number, :body
# validates :name, :email, :phone_number, :body, presence: true
end
mailers/volunteer_message_mailer.rb
class VolunteerMessageMailer < ApplicationMailer
# Subject can be set in your I18n file at config/locales/en.yml
# with the following lookup:
#
# en.volunteer_message_mailer.volunteer.subject
#
def volunteer(volunteer_message)
#body = volunteer_message.body
#subject = "Volunteer Request sent from www.myapp.com"
mail to: "myemail#example.com", from: volunteer_message.email
end
end
volunteer_messages_controller.rb
class VolunteerMessagesController < ApplicationController
def new
#volunteer_message = VolunteerMessage.new
end
def create
#volunteer_message = VolunteerMessage.new volunteer_message_params
if #volunteer_message.valid?
VolunteerMessageMailer.volunteer(#volunteer_message).deliver_now
redirect_to new_volunteer_message_url
flash.now[:notice] = "We have received your volunteer request and will be in touch soon!"
else
flash.now[:notice] = "There was an error sending your volunteer request. Please try again."
render :new
end
end
private
def volunteer_message_params
params.require(:volunteer_message).permit(:name, :email, :phone_number, :body)
end
end
pages_controller.rb
class PagesController < ApplicationController
def volunteer
#lead = Lead.new
#volunteer_message = VolunteerMessage.new
end
end
development.rb
# Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = true
config.action_mailer.perform_deliveries = true
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: 'smtp.gmail.com',
port: 587,
domain: 'gmail.com',
enable_starttls_auto: true,
user_name: 'me#gmail.com',
password: 'gmailapppassword',
authentication: 'plain'
}
Not sure what else I can add here. I do not think I even need he stmp_settings to see action mailer actually show the template of the email being sent?
Also I'm guessing it is somehting to do with the form and the route because ive added puts messages into the create action on the volunteer_message controller and do not see them in my server log.
I'm not getting any errors when pressing submit. I do notice the params going into the url but that's it. it stays there and when refreshes stays on the same screen.
example:
http://localhost:3000/volunteer?utf8=%E2%9C%93&authenticity_token=AZ%2FAflVf%2BlqRUYm45Jo82wAMpq%2B%2BY%2F93piLbeRXdK5n%2FQIWhuaUL3Oe2%2FSwzR%2FCLvj%2FAKW%2BBgD8dPd8vJYRDBA%3D%3D&volunteer_message%5Bname%5D=test+name&volunteer_message%5Bemail%5D=email%40test.com&volunteer_message%5Bphone_number%5D=88888888&volunteer_message%5Bbody%5D=test+email&commit=Send
Is the clue in the server text in the image that shows params going to the pages controller. I do not really want that. Just want the partial to be there but the action to work of the create action in the volunteer_messages controller.
Any help be much appreciated. Thanks.

How to resolve Errno::ECONNREFUSED in UsersController#create error in ROR

Can anybody help me to resolve this following error.I am trying to send an email but it failed to send and throws some error.
Error:
Errno::ECONNREFUSED in UsersController#create
No connection could be made because the target machine actively refused it. - connect(2)
app/controllers/users_controller.rb:8:in `create'
My code snippets are given below.
views/users/index.html.erb
<h1>Send email to your friend</h1>
<%= form_for #user,:url => {:action => 'create'} do |f| %>
<%= f.text_field:name,placeholder:"Enter your name" %><br>
<%= f.email_field:email,placeholder:"Enter your email" %><br>
<%= f.submit "Send" %>
<% end %>
views/users/new.html.erb
<h1>Successfully registered</h1>
views/users/success.html.erb
<h1>Email sent successfully</h1>
controller/users_controller.rb
class UsersController < ApplicationController
def index
#user=User.new
end
def create
#user=User.new(users_params)
if #user.save
UserMailer.registration_confirmation(#user).deliver
redirect_to :action => 'success'
else
render :'index'
end
end
def new
end
def success
end
private
def users_params
params.require(:user).permit(:name, :email)
end
end
views/user_mailer/registration_confirmation.text.erb
<%= #user.name%>
<h1>Thank you for registering</h1>
Click <%= link_to "here",users_new_path %>
mailer/user_mailer.rb
class UserMailer < ApplicationMailer
default :from => "w5call.w5rtc#gmail.com"
def registration_confirmation(user)
#user=user
mail(:to => user.email, :subject => "Registered")
end
end
config/initializers/setup_mail.rb
config.action_mailer.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:user_name => "w5call.w5rtc#gmail.com",
:password => "w5rtc123#",
:authentication => "plain",
:enable_starttls_auto => true
}
endActionMailer::Base.default_url_options[:host] = "localhost:3000"
development.rb
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false
# Do not eager load code on boot.
config.eager_load = false
# Show full error reports and disable caching.
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = true
# Print deprecation notices to the Rails logger.
config.active_support.deprecation = :log
# Raise an error on page load if there are pending migrations.
config.active_record.migration_error = :page_load
# Debug mode disables concatenation and preprocessing of assets.
# This option may cause significant delays in view rendering with a large
# number of complex assets.
config.assets.debug = true
# Asset digests allow you to set far-future HTTP expiration dates on all assets,
# yet still be able to expire them through the digest params.
config.assets.digest = true
# Adds additional error checking when serving assets at runtime.
# Checks for improperly declared sprockets dependencies.
# Raises helpful error messages.
config.assets.raise_runtime_errors = true
# Raises error for missing translations
# config.action_view.raise_on_missing_translations = true
config.action_mailer.delivery_method = :smtp
end
routes.rb
Rails.application.routes.draw do
root 'users#index'
post "users/create" => "users#create"
get "users/success" => "users#success"
get "users/new" => "users#new"
end
Actually i was referring this tutorial.I am using rails-4 and ruby 1.9.3.Please help me to resolve this error.

Export data to a .csv file on ruby app

I got an error
undefined method `form_for_results_path'
in my code to Export the data to a .csv file. Really don't know if I missed something. Here what I have:
item_controller
def export
CSV.open("result_data.csv", "w") do |csv|
csv << ["cod", "genre", "den_cont"]
end
end
In the view
<%= link_to 'Download CSV', form_for_results_path(#form), :method => :export %>
Thanks
Change it to this and read some more about rails basics.
<%= link_to 'Download CSV', controller: :item, action: :export%>
in your controller, you should do something like this, using rails send_data method:
def export
data = # your data in csv format
options = {
:filename => "some_name.csv",
:type => 'text/csv'
}
send_data(data, options)
end
you can also change your download link using a route_helper. add an entry in your routes file
get 'items/export', :as 'download_items_data"
then your link_to can look like this:
link_to 'Download CSV', download_items_data_path

omniauth identity not working on heroku with simple_form_for

I'm having trouble with Heroku not playing ball and throwing me this error
ActionController::RoutingError (No route matches [POST] "/auth/identity/register"):
I have the following working in dev.
model/user.rb
class User < OmniAuth::Identity::Models::ActiveRecord
has_many :services
controllers/users_controller.rb
def new
#user = env['omniauth.identity'] || User.new
end
users/new.html.erb
<%= simple_form_for #user, url: "/auth/identity/register" do |f| %><fieldset>
<legend><%= controller.action_name.capitalize %> User</legend>
<%= f.input :name, input_html: { name: "name" } %>
<%= f.input :email, input_html: { name: "email" } %>
<%= f.input :password, input_html: { name: "password" } %>
<%= f.input :password_confirmation, input_html: { name: "password_confirmation" } %>
<div class="form-actions">
<%= f.button :submit %>
<%= link_to 'Cancel', users_path, :class => 'btn' %>
</div></fieldset><% end %>
routes.rb
match "/auth/:service/callback" => 'services#create'
match "/auth/failure" => 'services#failure'
resources :users
This all works Perfectly on my machine but Heroku doesn't like it.
environments/development.rb and production.rb are the defaults created with "rails new..." with the following added:-
Rails.application.config.middleware.use OmniAuth::Builder do
require 'openid/store/filesystem'
provider :identity, fields: [:name, :email],
model: User,
on_failed_registration: lambda { |env|
UsersController.action(:new).call(env)
}
# generic openid
provider :open_id, :store => OpenID::Store::Filesystem.new('./tmp'), :name => 'openid'end
Hope this all makes sense and someone has the answer. Any and all help muchly appreciated.
Regards
Ok, I found the answer, just not sure why this is so though. Could be another question later if I don't find it here in stackoverflow.
Anyways, I was following this Excellent guide on www.communityguides.eu and put the omniauth configurations in development.rb and production.rb. Which made perfect sense as the OpenID::Store paths were different being:-
development.rb
OpenID::Store::Filesystem.new('/tmp')
production.rb
OpenID::Store::Filesystem.new('./tmp')
The Answer...
Put the omniauth configurations in initializers/Omniauth.rb
This means I now have to change this file every time I push to Heroku, but Heroku thanks me and allows my app to run nicely.
The question this raises for me (which I'm sure is answered elsewhere). What is the difference in the load order from Heroku and our Dev environments? Heroku appears to be loading initializers before the environment configs. And one more...anyone know a workaround that will save me having to update the Omniauth initializer file every time I want to push to Heroku ? :)
Thanx for reading and I hope this helps save someone some time.

ActionMailer 3 without Rails

I'm writing a small Ruby program that will pull records from a database and send an HTML email daily. I'm attempting to use ActionMailer 3.0.3 for this, but I'm running in to issues. All the searching I've done so far on using ActionMailer outside of Rails applies to versions prior to version 3. Could someone point me in the right direction of where to find resources on how to do this? Here's where I am so far on my mailer file:
# lib/bug_mailer.rb
require 'action_mailer'
ActionMailer::Base.delivery_method = :file
class BugMailer < ActionMailer::Base
def daily_email
mail(
:to => "example#mail.com",
:from => "example#mail.com",
:subject => "testing mail"
)
end
end
BugMailer.daily_email.deliver
I'm definitely stuck on where to put my views. Every attempt I've made to tell ActionMailer where my templates are has failed.
I guess I should also ask if there's a different way to go about accomplishing this program. Basically, I'm doing everything from scratch at this point. Obviously what makes Rails awesome is it's convention, so is trying to use parts of Rails on their own a waste of time? Is there a way to get the Rails-like environment without creating a full-blown Rails app?
After some serious debugging, I found how to configure it.
file mailer.rb
require 'action_mailer'
ActionMailer::Base.raise_delivery_errors = true
ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "domain.com.ar",
:authentication => :plain,
:user_name => "test#domain.com.ar",
:password => "passw0rd",
:enable_starttls_auto => true
}
ActionMailer::Base.view_paths= File.dirname(__FILE__)
class Mailer < ActionMailer::Base
def daily_email
#var = "var"
mail( :to => "myemail#gmail.com",
:from => "test#domain.com.ar",
:subject => "testing mail") do |format|
format.text
format.html
end
end
end
email = Mailer.daily_email
puts email
email.deliver
file mailer/daily_email.html.erb
<p>this is an html email</p>
<p> and this is a variable <%= #var %> </p>
file mailer/daily_email.text.erb
this is a text email
and this is a variable <%= #var %>
Nice question! It helped me to understand a bit more how Rails 3 works :)
It took me a while to get this to work in (non-)Rails 4. I suspect it's just because I have ':require => false' all over my Gemfile, but I needed to add the following to make it work:
require 'action_view/record_identifier'
require 'action_view/helpers'
require 'action_mailer'
Without the above code, I kept getting a NoMethodError with undefined method 'assign_controller'.
After that, I configured ActionMailer as follows:
ActionMailer::Base.smtp_settings = {
address: 'localhost', port: '25', authentication: :plain
}
ActionMailer::Base.default from: 'noreply#example.com'
ActionMailer::Base.raise_delivery_errors = true
ActionMailer::Base.logger = Logger.new(STDOUT)
ActionMailer::Base.logger.level = Logger::DEBUG
ActionMailer::Base.view_paths = [
File.join(File.expand_path("../../", __FILE__), 'views', 'mailers')
# Note that this is an Array
]
The templates go in lib/<GEM_NAME>/views/mailers/<MAILER_CLASS_NAME>/<MAILER_ACTION_NAME>.erb (MAILER_ACTION_NAME is the public instance method of your mailer class that you call to send the email).
Lastly, don't forget to put this in your spec_helper:
ActionMailer::Base.delivery_method = :test

Resources