I have the following HAML snippet being called when constructing an email to send to the user.
%p
Please <a href="#{base_url}/verify/#{user.primary_email.email}/#{user.registration_token}">click this link to confirm your email address</a>. You will then be logged in and can choose a password and continue the process of confirming your identity.
The user object defines the method primary_email
def primary_email()
result = self.emails.first(:conditions => {:primary => true})
puts "DEBUG: No Primary Email address found." unless result
puts "DEBUG: Primary Email address found was #{result.email}" if result
return result
end
but I get the error message
NoMethodError - undefined method `primary_email' for #<ActiveRecord::Relation:0x10f0d3a58>:
/Users/davesag/src/git/showpony3/rack/ruby/1.8/gems/activerecord-3.0.7/lib/active_record/relation.rb:374:in `method_missing'
./views/user_notifications/confirm_registration.haml:30:in `__tilt_2272398620'
./views/user_notifications/confirm_registration.haml:-7:in `instance_eval'
./views/user_notifications/confirm_registration.haml:-7:in `__tilt_2272398620'
/Users/davesag/src/git/showpony3/rack/ruby/1.8/gems/tilt-1.3.2/lib/tilt/template.rb:140:in `call'
/Users/davesag/src/git/showpony3/rack/ruby/1.8/gems/tilt-1.3.2/lib/tilt/template.rb:140:in `cached_evaluate'
/Users/davesag/src/git/showpony3/rack/ruby/1.8/gems/tilt-1.3.2/lib/tilt/template.rb:127:in `evaluate'
/Users/davesag/src/git/showpony3/rack/ruby/1.8/gems/tilt-1.3.2/lib/tilt/haml.rb:24:in `evaluate'
/Users/davesag/src/git/showpony3/rack/ruby/1.8/gems/tilt-1.3.2/lib/tilt/template.rb:76:in `render'
/Users/davesag/src/git/showpony3/rack/ruby/1.8/gems/sinatra-1.2.6/lib/sinatra/base.rb:563:in `render'
/Users/davesag/src/git/showpony3/rack/ruby/1.8/gems/sinatra-1.2.6/lib/sinatra/base.rb:463:in `haml'
./showpony.rb:256:in `build_messge_for'
In my simple unit test I test the primary_email method
george = setup_dummy_user("George")
assert george.primary_email.email == GEORGE_TEST_EMAIL
and that passes fine.
When I trigger the sending of this template it works once and then fails on the second send within the same request. (an Admin User and test user each get sent the same notification email when I test this via the browser)
what’s also weird is that in my logs I see the calls to the primary_email method being made. (actual emails redacted)
org = {"number"=>"34567890", "name"=>"Test Limited", "country"=>"au", "website"=>"http://www.testing.com"}
people = [{"name"=>"Test 1", "username"=>nil, "roles"=>[{"name"=>"admin"}, {"name"=>"billing"}], "email"=>"##############"}, {"name"=>"Test 2", "username"=>nil, "roles"=>[], "email"=>"@@@@@@@@@@@@@@@@@"}]
DEBUG: Primary Email address found was ##############
Sending confirmation email to ##############
DEBUG: Primary Email address found was ##############
Sending confirmation email to @@@@@@@@@@@@@@@@@
DEBUG: Primary Email address found was @@@@@@@@@@@@@@@@@
NoMethodError - undefined method `primary_email' for#<ActiveRecord::Relation:0x10ea44e58>:
any clues?
Using most recent Sinatra on Ruby 1.8.7 with most recent ActiveRecord and HAML.
The actual sinatra route that is triggering the request to send an email is as follows: Note the loop down the bottom that goes through each user supplied (via JSON) and sends them an email. That process triggers the build of a HAML template with the User as a local template variable.
It works okay for the first user but not for the second.
post '/register' do
content_type :json
req = JSON.parse request.body.read
if req['organisation'] == nil
puts req.inspect
return {:success => false, :error => "Request did not contain a proper Registration_Request object." }.to_json
end
org = req['organisation']
people = req['people']
message = "You (#{people[0]['name']} #{people[0]['email']}) have applied for membership on behalf of #{org['name']} (Company Number #{org['number']})."
@@log.debug "org = #{org.inspect}"
# do we have this org already?
oo = Organisation.find_by_name(org['name'])
if oo
@@log.debug "Found exisiting Org #{oo.inspect}"
return {:success => false, :error => "An organisation with that name is already a Member" }.to_json
end
these_people = []
begin
ActiveRecord::Base.transaction do
o = Organisation.create(:name => org['name'],
:number => org['number'],
:website => org['website'],
:country => org['country'])
@@log.debug "people = #{people.inspect}"
people.each {|person|
p = User.create(:name => person['name'], :username => person['email'], :password => random_password)
p.set_email({:email => person['email'], :primary => true})
p.organisation = o
person['roles'].each {|role|
p.add_role(role['name'])
}
p.set_preference("HTML_EMAIL", "true")
p.save!
these_people << p
}
end
end
# send a secure notification to settings.notification_email
send_system_email 'Membership Application received', :'system_notifications/registration', {:incoming_org => org, :incoming_people => people }
# send an email_validation_request email to each user email.
these_people.each {|p|
@@log.debug "Sending confirmation email to #{p.primary_email.email}"
send_user_email p, 'Please confirm your account details', :'user_notifications/confirm_registration', {:user => p }
}
return {:success => true, :message => message }.to_json
end
careful inspection of your error shows that you are trying to call “primary_email” method not on ActiveRecord object, but on Relation object
this can happen for example if you are getting your “user” variable in the following way
because “where” returns not array of ActiveRecords, but Relation object
to get the actual AR object you can try
or