我试图在嵌套属性表单更新后发送电子邮件通知,但我一直碰到这个错误,我认为是因为我在委员会模型更新数据库中的对象之前发送电子邮件通知因此我获得Property.councils.email的nil,非常感谢任何帮助。
物业邮件程序
class PropertyMailer < ActionMailer::Base
default from: "myemail@gmail.com"
def welcome_email(property, tenants, councils)
@property = property
@tenants = tenants
@councils = property.councils
mail(:to => property.councils.first.email, subject: 'Here are your property details')
end
end
property.rb
class Property < ActiveRecord::Base
has_many :council_histories
accepts_nested_attributes_for :council_histories, :reject_if => :send_email
has_many :councils, through: :council_histories, :foreign_key => :council_id
accepts_nested_attributes_for :councils
def send_email
if council_histories.where(council_id_changed?)
PropertyMailer.welcome_email(self, tenants, councils).deliver
end
end
end
'属性/构建控制器'嵌套控制器,使用邪恶的向导表单gem,构建一个多步骤表单。
class Properties::BuildController < ApplicationController
include Wicked::Wizard
steps :tenant, :meter, :council, :confirmed
def show
@property = Property.find(params[:property_id])
@tenants = @property.tenants.new(params[:tenant_id])
@meter = @property.build_meter
@property.council_histories.build do |council_history|
@council = council_history.build_council
end
render_wizard
end
def update
@property = Property.find(params[:property_id])
params[:property][:status] = step.to_s
params[:property][:status] = 'active' if step == steps.last
@property.update_attributes(params[:property])
render_wizard @property
end
end
表单视图
<%= simple_form_for @property, url: wizard_path, :method => 'put' do |f| %>
<%= f.simple_fields_for :council_histories do |builder| %>
<%= builder.input :property_id, as: :hidden, input_html: { value: @property.id } %>
<%= builder.input :council_id, :collection => Council.all %>
<%= builder.submit %>
<% end %>
<% end %>
答案 0 :(得分:1)
正如Marek Lipka所说,property.councils最有可能返回一个空哈希,但这只是故事的一部分。我认为问题出在您的Property
模型中,使用此行:
has_many :council_histories
accepts_nested_attributes_for :council_histories, :reject_if => :send_email
^^
This is the problem here
您的原始假设是正确的,我相信您是在:councils
关系有机会填充之前尝试发送电子邮件的。顾名思义,:reject_if
方法用于在某些情况下丢弃数据(我自己从不使用它,所以不能想到任何好的例子,但我确信有很多)。 Check here for more info
您是否绝对需要在对象保留之前发送电子邮件?如果没有,可能另一种方法是使用ActiveRecord::Callback方法之一,例如after_commit
,如下所示:
class Property < ActiveRecord::Base
after_commit :send_email
# Remainder of model code....
答案 1 :(得分:0)
您的property.councils
调用返回空集。