AbstractController::DoubleRenderError with my respond_to in rspec - ruby

I got this Rails3 action:
def export
respond_to do |format|
format.tdl { render :xml => #template.export_as_tdl and return }
format.json { render :json => #template.export_as_json }
end
end
and filter before the export:
def find_environment
#environment = KTEnvironment.find(params[:environment_id])
raise HttpErrors::NotFound, _("Couldn't find environment '#{params[:environment_id]}'") if #environment.nil?
#environment
end
and this rspec:
describe "export" do
it "should call export_as_json" do
#tpl.should_receive(:export_as_json)
get :export, :id => TEMPLATE_ID
end
it "should call export_as_tdl" do
#tpl.should_receive(:export_as_tdl)
get :export, :id => TEMPLATE_ID, :format => 'tdl'
end
end
I also defined the following MIME type:
Mime::Type.register "application/tdl-xml", :tdl
When I try to run my rspec tests, I am constantly getting:
1) Api::TemplatesController export should call export_as_tdl
Failure/Error: get :export, :id => TEMPLATE_ID, :format => 'tdl'
AbstractController::DoubleRenderError:
Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like "redirect_to(...) and return".
# ./app/controllers/api/api_controller.rb:135:in `render_exception'
# ./app/controllers/api/api_controller.rb:133:in `render_exception'
# ./app/controllers/api/api_controller.rb:22:in `__bind_1314974553_619675'
# ./spec/controllers/api/templates_controller_spec.rb:178
I have no clue what is happening there. This is my exception rendering code:
def render_wrapped_exception(status_code, ex)
logger.error "*** ERROR: #{ex.message} (#{status_code}) ***"
logger.error "REQUEST URL: #{request.fullpath}"
logger.error pp_exception(ex.original.nil? ? ex : ex.original)
orig_message = (ex.original.nil? && '') || ex.original.message
respond_to do |format|
format.json do
render :json => {
:errors => [ ex.message, orig_message ]
}, :status => status_code
end
format.all do
render :text => "#{ex.message} (#{orig_message})",
:status => status_code
end
end
end
Ah so the render_exception general method in my api_controller is called. It looks like:
def render_exception(status_code, exception)
logger.error pp_exception(exception)
respond_to do |format|
format.json { render :json => {:errors => [ exception.message ]}, :status => status_code }
format.all { render :text => exception.message, :status => status_code }
end
end

Try disabling your error handler, the root cause should come up on its own.

Related

Ruby Mailer: Wrong number of arguments

I'm working on building out my mailer, but I keep running into:
wrong number of arguments (0 for 1)
Call my crazy, but I feel like I defined everything correctly:
Controller (truncated for brevity):
def create
#cms484 = Cms484.new(cms484_params)
respond_to do |format|
if #cms484.save
SendLink.message(#cms484).deliver_later
format.html { redirect_to cms484s_path, notice: 'Cms484 was successfully created.' }
format.json { render :show, status: :created, location: #cms484 }
else
format.html { render :new }
format.json { render json: #cms484.errors, status: :unprocessable_entity }
end
end
SendLink.rb:
class SendLink < ApplicationMailer
def message(cms484)
#cms484 = cms484
mail(
:subject => 'Hello from Postmark',
:to => #cms484.recipient ,
:from => 'info#mysite.com',
:html_body => '<strong>Hello</strong> user!.',
end
end
Can anybody else see the needle in the haystack or am I missing something else entirely?
I'm using Postmark for delivery if that matters, and have those parameters defined in my application.rb file as per the documentation. Think this is a simpler matter though.
Edit
The complete error:
Completed 500 Internal Server Error in 76ms
ArgumentError (wrong number of arguments (0 for 1)):
app/mailers/send_link.rb:2:in `message'
app/mailers/send_link.rb:4:in `message'
app/controllers/cms484s_controller.rb:38:in `block in create'
app/controllers/cms484s_controller.rb:36:in `create'
I had a similar issue where I named my ActionMailer method "message" it turns out it was a reserved word in Rails and threw an error.
I would assume that "mail" was a reserved word where "email" was not.
mail ... line in SendLink.rb looks wrong , change it to,
mail(
:subject => 'Hello from Postmark',
:to => #cms484.recipient ,
:from => 'info#mysite.com',
:html_body => '<strong>Hello</strong> user!.')
Ok, so I decided to re-write it and behold - it works. Why or what's different than the previous version(other than the method email vs mail, surely that can't be it?), I have no idea. If you can see what it is, Please point it out to me!
Send_link.rb:
class SendLink < ApplicationMailer
def email(cms484)
#cms484 = cms484
mail(
:subject => 'Hello from Postmark',
:to => #cms484.recipient ,
:from => 'info#mysite.com',
)
end
end
Controller:
def create
#cms484 = Cms484.new(cms484_params)
respond_to do |format|
if #cms484.save
SendLink.email(#cms484).deliver_later
format.html { redirect_to cms484s_path, notice: 'Cms484 was successfully created.' }
format.json { render :show, status: :created, location: #cms484 }
else
format.html { render :new }
format.json { render json: #cms484.errors, status: :unprocessable_entity }
end
end
end

Registering new users with Devise in Rails 4

I am new to rails and working on a rails application.
I have installed the Devise gem and find it helpful in many areas, however I cannot create a new user unless I do it on the Rails Console. I find this especially frustrating. Does anyone have any suggestions or solutions?
When I sign up as an employee I get the following error "CanCan::AccessDenied in JobsController#index"
Also please note that when I verified my user model in devise and I have already included "include Devise::Models::DatabaseAuthenticatable"
My jobs_controller.rb file
def index
#users = User.all
#user = current_user
#jobs = Job.all
#jobs = Job.paginate(:page => params[:page], :per_page => 3)
end
# GET /jobs/1
# GET /jobs/1.json
def show
end
# GET /jobs/new
def new
#job = Job.new(:date => Time.now, :date_of_loss => Time.now, :sign_date => Time.now, :time_called_in => Time.now)
end
# GET /jobs/1/edit
def edit
end
# POST /jobs
# POST /jobs.json
def create
#job = Job.new(job_params)
respond_to do |format|
if #job.save
format.html { redirect_to #job, notice: 'Job was successfully created.' }
format.json { render action: 'show', status: :created, location: #job }
else
format.html { render action: 'new' }
format.json { render json: #job.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /jobs/1
# PATCH/PUT /jobs/1.json
def update
respond_to do |format|
if #job.update(job_params)
format.html { redirect_to #job, notice: 'Job was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #job.errors, status: :unprocessable_entity }
end
end
end
# DELETE /jobs/1
# DELETE /jobs/1.json
def destroy
#job.destroy
respond_to do |format|
format.html { redirect_to jobs_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_job
#job = Job.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def job_params
params.require(:job).permit(:date, :time_called_in, :date_of_loss, :contact, :job_address, :city, :postal_code, :site_phone, :work_phone, :cell_phone, :email, :referred_by, :insurance_company, :policy_number, :claim_number, :broker, :insurance_address, :insurance_city, :insurance_province, :insurance_postal_code, :insurance_phone, :insurance_contact, :insurance_email, :customer_name, :customer_address, :authorized, :signed_by_name, :sign_date, :signature, :contact_first_name, :contact_last_name)
end
end
My ability model looks like this
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.role == "admin"
can :manage, :all
elsif user.role == "manager"
can [:read, :update, :create], [Job, Equipment]
#can [:read, :update, :create], [Equipment]
elsif user.role == "employee"
can [:read, :update, :create], [Equipment, Job]
cannot [:create], [Job]
#can [:read, :update], [Equipment]
end
end
If you are getting this error: CanCan::AccessDenied in JobsController#index it's because your user is not authorized to access the JobsController#index method and has nothing to do with creating users.
Can you explain what you mean when you say you "Sign up as an employee"? Do you have a roles table or a boolean on the users table to indicate that a user is an employee?
Please post your Ability.rb class (possibly in app/models/ability.rb) as that's where the access controls for cancan are defined.
Try changing this:
user ||= User.new # guest user (not logged in)
to this:
user ||= User.new # guest user (not logged in)
puts "user.role = #{user.role}"
and then check your logs to see what the value of user.role is. I'm wondering if your user does not have the role that you think it does.

Get current stack trace in Ruby without raising an exception

I want to log the current backtrace (stacktrace) in a Rails 3 app without an exception occurring. Any idea how?
Why do I want this? I'm trying to trace the calls that are made when Rails looks for a template so that I can choose a part of the process to override (because I want to change the view path for a particular subclassed controller of mine).
I'd like to call it from the file: gems\actionpack-3.2.3\lib\action_dispatch\middleware\templates\rescues\missing_template.erb. I know that's not best practice, but I know it's downstream of the stack from where the search for templates occurs.
You can use Kernel#caller:
# /tmp/caller.rb
def foo
puts caller # Kernel#caller returns an array of strings
end
def bar
foo
end
def baz
bar
end
baz
Output:
caller.rb:8:in `bar'
caller.rb:12:in `baz'
caller.rb:15:in `<main>'
Try using
Thread.current.backtrace
I use this to show a custom error page when exception are raised.
rescue_from Exception do |exception|
logger.error exception.class
logger.error exception.message
logger.error exception.backtrace.join "\n"
#exception = exception
# ExceptionNotifier::Notifier.exception_notification env, #exception
respond_to do |format|
if [AbstractController::ActionNotFound, ActiveRecord::RecordNotFound, ActionController::RoutingError, ActionController::UnknownAction].include?(exception.class)
format.html { render :template => "errors/404", :status => 404 }
format.js { render :nothing => true, :status => 404 }
format.xml { render :nothing => true, :status => 404 }
elsif exception.class == CanCan::AccessDenied
format.html {
render :template => "errors/401", :status => 401 #, :layout => 'application'
}
# format.js { render :json => { :errors => [exception.message] }, :status => 401 }
# format.js { render :js => 'alert("Hello 401")' }
format.js { render :template => 'errors/401.js.erb' }
else
ExceptionNotifier::Notifier.exception_notification(env, exception).deliver
format.html { render :template => "errors/500", :status => 500 } #, :layout => 'im2/application' }
# format.js { render :nothing => true, :status => 500 }
format.js { render :template => 'errors/500.js.erb' }
end
end
end

Why does this rescue syntax work?

Ok so I have this method of an application I am working with and it works in production. My question why does this work? Is this new Ruby syntax?
def edit
load_elements(current_user) unless current_user.role?(:admin)
respond_to do |format|
format.json { render :json => #user }
format.xml { render :xml => #user }
format.html
end
rescue ActiveRecord::RecordNotFound
respond_to_not_found(:json, :xml, :html)
end
rescues do not need to be tied to an explicit begin when they're in a method, that's just the way the syntax is defined. For examples, see #19 here and this SO question, as well as the dupe above.
rescue can work alone . no need of begin and end always .
You can use rescue in its single line form to return a value when other things on the line go awry:
h = { :age => 10 }
h[:name].downcase # ERROR
h[:name].downcase rescue "No name"
rescue word is part of method definition
But in controllers better to rescue errors with rescue_from
try this
def edit
begin
load_elements(current_user) unless current_user.role?(:admin)
respond_to do |format|
format.json { render :json => #user }
format.xml { render :xml => #user }
format.html
end
rescue ActiveRecord::RecordNotFound
respond_to_not_found(:json, :xml, :html)
end
end

Element.update rjs error while using link_to_remote in rails

I am using rails 2.3.2
I have a link_to_remote functions
<%= link_to_remote "Comments ", {
:url => {:controller => "blogs",:action => "fetchcomments",:id => blog.id}} %> |
and the rails action as
def fetchcomments
unless params[:id].nil?
#blog = Blog.find(params[:id])
respond_to do |format|
format.js do
render :update do |page|
page.replace_html("comm", 'hi')
end
end
end
end
The above code throws me the error as
try {
Element.update("comm", "hi");
} catch (e) { alert('RJS error:\n\n' + e.toString());
alert('Element.update(\"comm\", \"hi\");'); throw e }
Please give me suggestions
Remove unless params[:id].nil? and it will work if you have an element with the id 'comm' on the page that makes the request. Of course it will replace whatever is inside with the word 'hi'.

Resources