Using Struct in ActionMailer preview - ruby-on-rails

I am testing one of my mailers using ActionMailer Preview and am using Struct to create my objects
class TransactionMailerPreview < ActionMailer::Preview
include Roadie::Rails::Automatic
def transaction_complete_mailer
orders = Struct.new(:image, :image_size, :mount, :frame, :frame_color)
transaction = Struct.new(:first_name, :email)
#transaction = transaction.new('Richard Lewis', 'test#gmail.com')
#orders = orders.new("Test Print Name", "10x8 Image Size", "10x8 Mount Size", "10x8 Frame Size", "White Frame")
TransactionMailer.transaction_complete_mailer(#transaction, #orders)
end
end
This is my actual mailer class
class TransactionMailer < ApplicationMailer
default from: ENV['EMAIL_ADDRESS']
def transaction_complete_mailer(transaction, orders)
#transaction = transaction
#orders = orders
attachments.inline['photography-logo-text.png'] = File.read(Rails.root.join('app', 'assets', 'images', 'photography-logo-text.png'))
mail(to: #transaction.email, subject: 'Your order from Glenn GB Photography') do |format|
format.html { render file: 'transaction_mailer/transaction_message.html.erb', layout: 'mailer' }
end
end
end
In my view I loop over the #orders as there could be multiple
transaction_message.htmnl.erb
<% #orders.each do |order| %>
<div class="order-summary">
<p><span class="bold">Print:</span><%= order.image %></p>
<p><span class="bold">Print Size:</span><%= order.image_size %></p>
<p><span class="bold">Mount:</span><%= order.mount %></p>
<p><span class="bold">Frame:</span><%= order.frame %></p>
<p><span class="bold">Frame Color:</span><%= order.frame_color %></p>
</div>
<% end %>
When I action this mailer in preview I get an error
undefined method `image' for "Test Print Name":String
I have two questions here
Why am I getting the error?
How would I create multiple order objects?

#orders is a singular object of type struct, but your your transaction_complete_mailer expects an array/collection named #orders. So when you call #orders.each do |order| in your Mailer, it's actually iterating through each key/value in the #orders struct object. This explains the error you're getting since "Test Print Name" is the first key declared in your Struct.
Wrapping your structs in an array should resolve the issue:
class TransactionMailerPreview < ActionMailer::Preview
include Roadie::Rails::Automatic
def transaction_complete_mailer
orders = Struct.new(:image, :image_size, :mount, :frame, :frame_color)
transaction = Struct.new(:first_name, :email)
#transaction = transaction.new('Richard Lewis', 'test#gmail.com')
#order = orders.new("Test Print Name", "10x8 Image Size", "10x8 Mount Size", "10x8 Frame Size", "White Frame") # Renamed to #order, since this is a single object
TransactionMailer.transaction_complete_mailer([#transaction], [#order])
end
end

Related

How to render an array in Rails

In my Rails application, I have a class Bar and a controller FooController.
class Bar
attr_accessor :id
end
class FooController < ApplicationController
def index
#rows = {}
bar = Bar.new
bar.id = 1
#rows[0] = bar
render "index"
end
end
In the view, I would like to render like this
<table>
<% #rows.each do |bar| %>
<tr>
<td><%= bar.id %></td>
</tr>
<% end %>
</table>
But it will throws error
undefined method `id' for [0, #<Bar:0x00007fc65db33320 #id=1>]:Array
If I render like this:
<%= #rows %>
the raw data of the array #rows will be rendered as:
{0=>#<Bar:0x00007fc65db33320 #id="1">}
How do I render the elements one by one?
The problem is that #rows = {} doesn't assign an array but a hash. And therefore #rows[0] = bar doesn't store bar as the first element in the array, but it stores bar under the key in the hash.
Just change your controller method to:
def index
#rows = []
bar = Bar.new
bar.id = 1
#rows << bar
render "index"
end

Get “wrong number of arguments” on ruby on rails

wrong number of arguments (given 2, expected 1)
SportsController
class SportsController < ApplicationController
def index
#sport = Sport.all
#events, #errors = Bapi::Inplay.all(query)
end
private
def query
params[:query, {}]
end
end
Sport index.html.erb
<% #sports.each do |sport| %>
<% #events(:sport_id => sport.id).each_slice(2) do |events| %>
I want send each sport.id to #enevts instance variable
Edited :
When send query as hash in SportsController its work!!
class SportsController < ApplicationController
def index
#sport = Sport.all
query = {:sport_id => 1}
#events, #errors = Bapi::Inplay.all(query)
end
private
def query
params[:query, {}]
end
end
Index.html.erb
<% #sports.each do |sport| %>
<% #events.each_slice(2) do |events| %>
params is a hash and method :[] can accept only 1 argument.
def query
params[:query] || {} # Will return :query part or empty Hash if it has nothing
end

Uninitialized constant error in my controller after adding a presenter

I added this to my controller:
class HtmlreportController < ApplicationController
def index
#report = Report.new
#report_presenter = ReportPresenter.new(#report_presenter)
end
end
Then added this presenter to /app/presenters
# app/presenters/htmlreport_presenter.rb
class ReportPresenter
def initialize(report)
#report = report
end
def pass_fail(view)
arrs = ['onemon.rb','twomon.rb','threemon.rb','fourmon.rb','fivemon.rb']
arrs.each do |arr|
shortname = File.basename("#{arr}", ".rb")
newest_file = Dir.glob("ScriptResults/#{shortname}/*").max
#reporter = File.readlines("/Users/username/Automation/Code/Reports/MonthlyTracking/#{newest_file}")
if #reporter.grep(/test failed/).any?
view.concat content_tag(:div, 'FAILED', class: 'results_fail')
else
view.concat content_tag(:div, 'PASSED', class: 'results_pass')
end
end
end
end
With this in my view:
<% title "HTML Report" %>
<!-- This is where the HTML Report lies -->
<h1>HTML Report for Marines.com Daily Monitoring</h1>
<div>View the grids below for the following results:</div>
<div id="results">
<div class="results_grid">
<div class="results_title">Xbox</div>
<%= #report_presenter.show_credentials(self) %>
</div>
</div>
But, I get this error when running it: uninitialized constant HtmlreportController::Report for the line #report = Report.new
How do I get it initialized to make it recognize the functions in my presenter into my view?

Rails update_attribute not found

i need update a single record attribute but i can´t. alumno_id is foreign key of model 'alumno'. the code show the records and if submit 'Aceptar' in one record, need a change the attribute estado to 1
in Model
class Postulacion < ActiveRecord::Base
attr_accessible :ramo, :estado, :alumno_id
belongs_to :alumno
end
in View
<h1>Lista de Postulaciones</h1>
<% #postulaciones.each do |p| %>
<% #id = p.id %>
<%= #id %>
<p>
<td><%= Alumno.find(p.alumno_id).full_name%></td>
<td><%='=> '+ p.ramo %></td>
<td><% if p.estado == 0 %>
<%= 'Pendiente =>' %>
<%= form_tag :action => 'aceptar' do %>
<%= submit_tag 'Aceptar' %></p>
<%end%>
<%else%>
<%='=> Aceptado' %>
<%end%>
</td>
</p>
<% end %>
in controller
class ListadoController < ApplicationController
def listar
#postulaciones = Postulacion.all
respond_to do |format|
format.html
format.json { render json: #postulaciones }
end
end
def aceptar
#postulacion = Postulacion.where(id: #id).first #Edit
#postulacion.estado = 1 #Edit
#postulacion.save #Edit
redirect_to "/"
end
end
Error "undefined method `update_attribute' for []:ActiveRecord::Relation"
Thanks
With this code:
#postulacion = Postulacion.where(alumno_id: #id )
You are declaring #postulacion as a collection, not as a single instance. You can fix this by calling .first:
#postulacion = Postulacion.where(alumno_id: #id ).first
Or by using find_by instead of where:
#postulacion = Postulacion.find_by(alumno_id: #id )
One other thing - this code isn't checking for the possibility that the Postulacion instance might not exist. You should add some logic to handle this...
Your #postulacion variable holds ActiveRecord::Relation instead of single ActiveRecord object. Try:
def acceptar
#postulacion = Postulacion.find_by_alumino_id(#id)
# ...
end
or, if you'd be using Rails 4:
#postulacion = Postulacion.find_by(alumino_id: #id)

Url helper is not available when rendering a partial from a class

I have a helper class that renders a partial to store the content in the database.
It works fine but when the view contains a url provided by the url helper
<%= link_to "Show project", projects_url, class: "button" %>
it throws the following exception
undefined local variable or method projects_url for #
The code to render in my helper named NotificationRender is
def render(options)
viewer = ActionView::Base.new()
viewer.view_paths = ActionController::Base.view_paths
viewer.extend ApplicationHelper
viewer.render options
end
I include this helper in a class Notification
class Notification < ActiveRecord::Base
include NotificationRender
.....
def self.create_for(user, event, params)
template = "notifications/_email_project"
list_params = {:template => template,:locals => params}
notification = Notification.new
notification.message = notification.render(list_params) #here I render the partial
notification.subject = I18n.t "subject.#{event}"
notification.to = user.email
notification.save
end
end

Resources