Rails: initializing global variable in event_mailer - ruby-on-rails

In my mailers/event_mailer class, I have a few methods. Each of these methods:
Receives a user hash an input
Turns the user hash into a global variable
calls a the corresponding .html.erb file from event_mailers to send email
Instead of repeating steps 1 & 2 for every method, is there a way to have that initialized once in a "constructor" for the event_mailer class?
Clarification Code:
Registrations Controller Code:
EventMailer.notify_admins(#user,subject,topic).deliver
event_mailer.rb code:
class EventMailer < ActionMailer::Base
##smtp_settings = {
..........
}
def notify_admins(user,subject,topic)
#user = user
#topic = topic
......
mail(:from => 'test#example.com', :to => 'someone#someone.com', :subject => subject)
end
def notify_accounts(user,subject,topic)
#user = user
#topic = topic
......
mail(:from => 'test#example.com', :to => 'someone#someone.com', :subject => subject)
end

Related

No route matches {:controller=>"stocks", :action=>"create"} RSpec Rails 3

I don't understand why I'm getting this error message when I run RSpec:
Failure/Error: post :create
ActionController::RoutingError:
No route matches {:controller=>"stocks", :action=>"create"}
The controller stocks exists, the action create exists, and the route it should be using is this:
match 'stocks/:user_id' => 'stocks#create', :via => :post, :as => :query
Route File:
FruthScreener::Application.routes.draw do
root :to => 'stocks#index' # add user_id
match 'stocks/:user_id' => 'stocks#create', :via => :post, :as => :query
match 'stocks/:user_id' => 'stocks#destroy', :via => :delete, :as => :reset
match 'stocks/:user_id/update' => "stocks#update_index", :via => :post
Stock Controller: (Yes, this will be DRYed up)
class StocksController < ApplicationController
def index
#user = User.create
#user_id_num = #user.id
#user.stocks = Stock.all
#user.save
selected_user_stocks = (UserStock.where("user_id = #{#user_id_num} AND selected = true")).take(25)
#stocks = UserStock.convert_to_stocks(selected_user_stocks)
#pages = Pagination.determine_num_pages(#user.stocks)
end
def update_index
#user_id_num = params[:user_id]
#user = User.find(#user_id_num)
selected_user_stocks = UserStock.where("user_id = #{#user_id_num} AND selected = true")
#stocks = UserStock.convert_to_stocks(selected_user_stocks)
#pages = Pagination.determine_num_pages(#stocks)
#stocks = Stock.display(#stocks, params[:pageNumber].to_i)
render partial: 'stock_data'
end
def create
UserStock.eliminate_stocks(params) # thinking it's like "creating" a new batch of stocks
#user_id_num = params[:user_id]
#user = User.find(#user_id_num)
selected_user_stocks = UserStock.where("user_id = #{#user_id_num} AND selected = true")
#stocks = UserStock.convert_to_stocks(selected_user_stocks)
#pages = Pagination.determine_num_pages(#stocks)
#stocks = Stock.display(#stocks, 1)
render partial: 'stock_data'
end
def destroy
stocks_to_reset = UserStock.where("user_id = #{params[:user_id]}")
stocks_to_reset.each do |user_stock|
user_stock.selected = true
user_stock.save
end
#user_id_num = params[:user_id]
#user = User.find(#user_id_num)
selected_user_stocks = UserStock.where("user_id = #{#user_id_num} AND selected = true")
#stocks = UserStock.convert_to_stocks(selected_user_stocks)
#pages = Pagination.determine_num_pages(#stocks)
#stocks = Stock.display(#stocks, 1)
render partial: 'stock_data'
end
end
Stock Controller Spec: (test at bottom is failing)
require 'spec_helper'
RSpec.configure do |config|
config.infer_spec_type_from_file_location!
end
describe StocksController do
context "index" do
before do
#user_count = User.all.count
#stock_count = Stock.all.count
get :index
end
it "should create a new user" do
expect(User.all.count).to eq(#user_count + 1)
end
it "should associate all stocks with the user" do
expect(User.last.stocks.count).to eq(#stock_count)
end
end
context "create" do # investigate why this isn't working...
it "should render the stock_list partial" do
user = User.create
post :create
response.should render_template(partial: "stock_list")
end
end
end
Thanks!!
match 'stocks/:user_id' => 'stocks#create', :via => :post, :as => :query
tells us that it needs :user_id to be a valid route.
post :create
has no :user_id... so it doesn't refer to a valid route.
I'd change it to
post :create, :user_id => user.id
post :create, params: {user_id: user.id}

Rails 3.1 mail encoding issue

I have a Payment mailer class that creates email:
class PaymentMailer < ActionMailer::Base
include LocaleWrapper
helper :application
def payment_notification(payment)
host = payment.try(:host)
#payment = payment
#user = payment.user
using_locale((#user && #user.locale) || I18n.locale) {
attachments["#{set_default_domain_name_from(host)}_receipt_#{Time.now.strftime("%Y_%m_%d")}.pdf"] = WickedPdf.new.pdf_from_string(
render_to_string(pdf: "#{set_default_domain_name_from(host)}_receipt_#{Time.now.strftime("%Y_%m_%d")}.pdf", template: filtre_mail_template_by_host(host), layout: "pdf.html"))
headers['Precedence'] = 'bulk'
mail(:to => #user.email, :subject => I18n.t("mailer_subjects.payment_completed"), :from => "no-reply##{set_default_domain_name_from(host)}") do |format|
format.text(:content_transfer_encoding => "base64")
format.html
end
}
end
I have observer method that saves email in the database:
def delivered_email(email)
Rails.logger.info email.inspect
html_body = (email.multipart? ? email.html_part : email).body.to_s
text_body = (email.multipart? ? email.text_part : email).body.to_s
outgoing_mail = OutgoingMail.new({
:to => email.to.join(', '),
:from => email.from.join(', '),
:subject => email.subject.to_s,
:sent_at => email.date,
:html_body => html_body,
:text_body => text_body,
:multipart => email.multipart?,
})
outgoing_mail.save
save_attachments(email, outgoing_mail)
end
Problem is with multipart email's plain text version, which returns ASCII 8bit string and mysql throws Mysql2::Error: Incorrect string value error.
(rdb:1) text_body
"N\x16\xA7\x93*.~\x8A\xF2\xA2\xEA\xDC\xA2{k\x89\xBB\xAD\x8A\x89\xD2y\xEA]}\xABmi\xC8fz{_\xA2\xBAZ\xCAg\xA7\xB5\xD7\xADj)l"
(rdb:1) text_body.encoding
#<Encoding:ASCII-8BIT>
I have tried using #force_encoding method, but there is no success:
(rdb:1) text_body.force_encoding("UTF-8")
"N\u0016\xA7\x93*.~\x8A\xF2\xA2\xEAܢ{k\x89\xBB\xAD\x8A\x89\xD2y\xEA]}\xABmi\xC8fz{_\xA2\xBAZ\xCAg\xA7\xB5\u05EDj)l"
Why am i getting ASCII 8bit string instead of UTF-8?

How to add to options hash only if a condition is true?

In my Rails project I have this mailer class:
class ProjectMailer < ActionMailer::Base
def send_project_link(delivery)
#delivery = delivery
mail(:from => #delivery.sender_email,
:to => #delivery.recipient_email,
:bcc => [#delivery.sender_email],
:subject => #delivery.subject)
end
end
What is the cleanest way to either include or not include the key/value pair :bcc in the hash, depending on whether true or false is given?
Thanks for any help.
mail(
{
from: #delivery.sender_email,
to: #delivery.recipient_email,
subject: #delivery.subject,
}
.tap{|h| h[:bcc] = [#delivery.sender_email] if #delivery}
)
To not include the :bcc key in the options, you could do this:
class ProjectMailer < ActionMailer::Base
def send_project_link(delivery, send_with_bcc=false)
#delivery = delivery
mail_options = {
:from => #delivery.sender_email,
:to => #delivery.recipient_email,
:subject => #delivery.subject
}
mail_options[:bcc] = [#delivery.sender_email] if send_with_bcc
mail(mail_options)
end
end
I'd probably do this...
def send_project_link(delivery. bcc? = false)
#delivery = delivery
mail_options = {:from => #delivery.sender_email,
:to => #delivery.recipient_email,
:subject => #delivery.subject
}
mail_options[:bcc] = [#delivery.sender_email] if bcc?
mail mail_options
end

Undefined method `keys' for nil:NilClass error on rails

I tried to run web server and it shows the following error:
undefined method `keys' for nil:NilClass error on rails
Extracted source (around line #21):
shopsList = [st1, st2, st3, st4]
render :json => shopsList
end
end
Here are the files:
shop.rb
class Shop < ActiveRecord::Base
attr_accessor :name, :description, :comments
def initialize(name, description, comments)
#name = name
#description = description
#comments = []
end
end
comment.rb
class Comment
attr_accessor :id, :name, :content
def initialize(id, name, content)
#id = id
#name = name
#content = content
end
end
shops_controller.rb
class ShopsController < ApplicationController
def index
end
def shops
com1 = Comment.new("FX991", "Goat", "Delicious!")
com2 = Comment.new("F2888", "Cow", "Amazing!")
com3 = Comment.new("GH555", "Cat", "Yummm!")
com4 = Comment.new("HY666", "Fish", "Mouth watering!")
commentList = [com1, com2, com3, com4]
sh1 = Shop.new("AAAA", "Je", commentList[0])
sh2 = Shop.new("NNNN", "Te", commentList[1])
sh3 = Shop.new("CCCC", "Be", commentList[1])
sh4 = Shop.new("DDDD", "He", commentList[1])
shopsList = [sh1, sh2, sh3, sh4]
render :json => shopsList
end
end
When I tried changing render :json => shopsList to render :json => commentList, the comment list would show as json format in the server.
Also, is there something wrong with the way I access or declare the commentList array? The contents of the array won't show when I try to access it. It just displays "[]"
You need to pass a hash to render
try this
shopsList = [sh1, sh2, sh3, sh4]
render :json => {:success=>true, :data=>shopsList}
Can you please post the stacktrace?
I don`t think "render" is causing the error, I think it happens earlier on in the callstack.
#tested this, it is valid code
def mytest
data = ["1","2","3"]
render :json => data
end

Refactoring a hash to Object

I have a method that return a Hash and then I write the entries of hash in xml file. Iwant to convert this Hash to an object to store the entry and then write it to xml file...
My current code is like this
def entry(city)
{
:loc => ActionController::Integration::Session.new.url_for(:controller => 'cities', :action => 'show', :city_name => city.name, :host => #country_host.value),
:changefreq => 0.8,
:priority => 'monthly',
:lastmod => city.updated_at
}
end
The write_entry method is inside my writer class that writes this entry to xml file
def write_entry(entry)
url = Nokogiri::XML::Node.new( "url" , #xml_document )
%w{loc changefreq priority lastmod}.each do |node|
url << Nokogiri::XML::Node.new( node, #xml_document ).tap do |n|
n.content = entry[ node.to_sym ]
end
end
url.to_xml
end
Thanks
I might be way off here, but it seems like what you're trying to do is something like this:
First, figure out what makes sense as a class name for your new object. I'm going with Entry, because that's the name of your method:
class Entry
end
Then take all the "properties" of your hash and make them reader methods on the object:
class Entry
attr_reader :loc, :action, :changefreq, :priority, :lastmod
end
Next you need to decide how this object will be initialized. It seems like you will need both the city and #country_host for this:
class Entry
attr_reader :loc, :action, :changefreq, :priority, :last mod
def initialize(city, country_host_value)
#loc = ActionController::Integration::Session.new.url_for(:controller => 'cities', :action => 'show', :city_name => city.name, :host => country_host_value)
#changefreq = 0.8 # might actually want to just make this a constant
#priority = 'monthly' # another constant here???
#lastmod = city.updated_at
end
end
Finally add your XML builder method to the class:
class Entry
attr_reader :loc, :action, :changefreq, :priority, :last mod
def initialize(city, country_host_value)
#loc = ActionController::Integration::Session.new.url_for(:controller => 'cities', :action => 'show', :city_name => city.name, :host => country_host_value)
#changefreq = 0.8 # might actually want to just make this a constant
#priority = 'monthly' # another constant here???
#lastmod = city.updated_at
end
def write_entry_to_xml(xml_document)
url = Nokogiri::XML::Node.new( "url" , xml_document )
%w{loc changefreq priority lastmod}.each do |node|
url << Nokogiri::XML::Node.new( node, xml_document ).tap do |n|
n.content = send(node)
end
end
url.to_xml
end
end
Now that your hash has been refactored, you can update your other class(es) to use the new object:
class WhateverClassThisIs
def entry(city)
Entry.new(city, #country_host.value)
end
end
It's not clear how the XML writer method is being called, but you would need to update that as well to use the new write_entry_to_xml method, passing in the xml document as an argument.

Resources