Troubleshooting empty params[] hash since Rails3 Upgrade - ruby-on-rails-3

I have a named route that tests properly in the console and shows the :url_title which should be included in params[], yet params[] is always empty.
The question is, why is params[] empty? My expectation is it should have params[:url_title].
I also removed this route and used the default resource and params[] is still empty.
I've been checking params by using logger.
My app is an upgrade from Rails 2.3.5 to Rails 3.0.3.
Here's a code summary of what's going on.
# this is my route
match 'papers/:url_title' => 'papers#show', :as => :permalinkpaper
# this is link_to and the generated url being called
<%= link_to paper.title, paper_path(paper.url_title) %>
http://localhost:3000/papers/great-passion
# which properly matches to this controller#action for papers#show
def show
#paper = Paper.where(:url_title => params[:url_title]).first()
PaperHistory.add( current_user, #paper.id )
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #paper }
format.json { render :json => #paper }
format.mobile # { render :layout => false }
end
end
# which generals this error because the Paper looking returns noting because the params[:url_title] is nil
Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
# the log stack trace
Started GET "/papers/great-passion" for 127.0.0.1 at Mon Jan 24 23:04:04 -0600 2011
Processing by PapersController#show as HTML
SQL (0.7ms) SHOW TABLES
SQL (0.5ms) SHOW TABLES
Paper Load (0.7ms) SELECT `papers`.* FROM `papers` WHERE (`papers`.`url_title` IS NULL) ORDER BY title LIMIT 1
Completed in 119ms
RuntimeError (Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id):
app/controllers/papers_controller.rb:43:in `show'
# I've validated the route in the console and it seems to know :url_title is the proper value
>> r = ActionController::Routing::Routes
>> r.recognize_path "/papers/great-passion"
=> {:action=>"show", :url_title=>"great-passion", :controller=>"papers"}
UPDATE: I have found that params[] are NOT empty when values are in the URL, such as when performing a search.
http://localhost:3000/papers?utf8=%E2%9C%93&keywords=passion
This successfully produces
Started GET "/papers?utf8=%E2%9C%93&keywords=passion" for 127.0.0.1 at Tue Jan 25 00:20:07 -0600 2011
Processing by PapersController#index as HTML
Parameters: {"utf8"=>"✓", "keywords"=>"passion"}
params: utf8✓keywordspassion

Thanks to all for the help. I was able to disassemble my app piece by piece and finally get params[] to show up.
The culprit was the open_id_authentication plugin.
I had some plugins in the vendors directory, so I removed them all and after hurdling a few resulting errors (b/c the plugins were now missing) everything worked. I systematically replaced plugins, and when I got to open_id_authentication found that the params[] again disappeared.

I had a different solution for this problem that I'll post here just in case somebody runs into the same issue. I was working on a password reset part of the site and tried various things such as putting the URL in manually, specifying the controller and action, using a bare (minimal) form and such, but all of it failed. The error given was the e-mail parameter was blank.
A look into the Exceptional logs showed that not just the e-mail parameter was blank, but even the UTF-8 check mark was missing. The only things in the params hash were the controller and action. Reloading the page also didn't turn up the usual spiel about re-submitting information.
It turns out the problem was in SSL. The page was trying to use SSL but didn't have permission and it was somehow silently killing the form. Hope that helps somebody.

Related

Cloudmailin gets 500 from Heroku when delivering e-mails

I'm using the Cloudmailin addon to receive e-mail from my Heroku app. However, Cloudmailin has not been able to deliver - or, rather, it gets 500 from Heroku every time (so the address is correct).
The error in Heroku logs is
Started POST "/incoming_mails" for 109.107.35.53 at 2013-02-27 08:54:22 +0000
2013-02-27T08:54:23+00:00 app[web.1]: Entering the controller! Controlling the e-mail!
2013-02-27T08:54:23+00:00 app[web.1]:
2013-02-27T08:54:23+00:00 app[web.1]: NoMethodError (undefined method `[]' for nil:NilClass):
2013-02-27T08:54:23+00:00 app[web.1]: app/controllers/incoming_mails_controller.rb:7:in `create'
My routing is correct; the "Entering the controller! Controlling the e-mail!" comes from the puts at the beginning of the class, so the class definitely gets entered.
# routes.rb
post '/incoming_mails' => 'incoming_mails#create'
The file itself looks like this:
# /app/controllers/incoming_mails_controller.rb
class IncomingMailsController < ApplicationController
skip_before_filter :verify_authenticity_token
def create
puts "Entering the controller! Controlling the e-mail!"
Rails.logger.info params[:headers][:subject]
Rails.logger.info params[:plain]
Rails.logger.info params[:html]
if User.all.map(&:email).include? params[:envelope][:from] # check if user is registered
#thought = Thought.new
#thought.body = params[:plain].split("\n").first
#thought.user = User.where(:email => params[:envelope][:from])
#thought.date = DateTime.now
if #thought.save
render :text => 'Success', :status => 200
else
render :text => 'Internal failure', :status => 501
end
else
render :text => 'Unknown user', :status => 404 # 404 would reject the mail
end
end
end
User and Thought are database resources used elsewhere without a problem. The saving procedure is the same that works in scaffolding-generated Thought controller. The params and Rails.logger logic I copied from a Cloudmailin Rails 3 example.
I'm really confused - where am I going wrong? I'd really appreciate any pointers.
It turns out, this is why you shouldn't code while sleep-deprived. The problem was simple: there is no such thing as params[:envelope][:from], there is only params[:from]). My assumption that :from would be a sub-element of :envelope was probably formed by looking at the pattern in the second "Cloudmailin in Rails on Heroku" example, where a code used to log subject is Rails.logger.log params[:envelope][:subject].
I realized this was the error after reading the API documentation for 'original' Cloudmailin format. It was exceptionally silly of me not to have found / looked for this resource in the first place.
After fixing this, the code still didn't work, because User.where(:email => params[:from]) only returned a Relation object, while User object was expected. The error in Heroku logs was the following:
ActiveRecord::AssociationTypeMismatch (User(#29025160) expected,
got ActiveRecord::Relation(#12334440)):
Since there can only be one user with some e-mail, the fix User.where(:email => params[:from]).first has no side-effects and results in correct behavior.

Rails: controller method reading wrong model

I've got two models (Articles and Documents) and I'm working with them from a third controller (called Share). I've written this method in that controller to track clicks on articles and the like:
def read_more(a)
#article = Article.find(a)
impressionist(#article)
end
And for some bizarre reason my app tries to find a Document with an ID of, say, 17, instead of an Article. I'm completely stumped.
Any ideas? Cheers!
EDIT:
The log readout is:
Started GET "/share/read_more/17" for 127.0.0.1 at 2012-12-17 09:37:49 +1100
Processing by ShareController#show as JS
Parameters: {"ftp"=>"read_more", "id"=>"17"}
Document Load (0.1ms) SELECT "documents".* FROM "documents" WHERE "documents"."id" = ? LIMIT 1 [["id", "17"]]
Completed 500 Internal Server Error in 1ms
ActiveRecord::RecordNotFound (Couldn't find Document with id=17):
I figured out the answer, should anyone else come into a similar issue.
def read_more
#article = Article.find(params[:id])
impressionist(#article)
render :json => "Read."
end
Apparently you can't have arguments in controller methods.

Rails 3.1 custom controller action keeps asking for ID even when route is specified

I'm trying to add a custom action ('last_five') to a controller.
My routes are specified as:
people_last_five GET /people/last_five(.:format) {:action=>"last_five", :controller=>"people"}
(i.e. that's the output of rake_routes).
But when I browse to /people/last_five I get the following error.
Started GET "/people/last_five" for XXX.XX.XXX.XXX at Sun May 15 22:03:18 +0000 2011
Processing by PeopleController#last_five as HTML
User Load (1.4ms)^[[0m SELECT users.* FROM users WHERE users.id = 3 LIMIT 1
Completed in 86ms
ActiveRecord::RecordNotFound (Couldn't find Person without an ID):
I thought this was a problem in my routes.rb
In my routes.rb I currently have:
get 'people/last_five'
resources :people
I've also tried
resources :people do
get 'last_five', :on => collection
end
but that gives the same results.
Why is rails trying to get an ID when there is no "/:id/" in the route?
This even happens when I specify the route as '/people/:id/last_five' and pass it a dummy id. In that case it still tells me ActiveRecord::RecordNotFound (Couldn't find Person without an ID).
I have this problem even when I reduce the action itself to a stub for debugging, so I don't think that's the problem. In my controller:
# GET /people/last_five
def last_five
logger.info "LAST FIVE IS BEING CALLED"
##people = Person.last_five
#respond_with #people do |format|
# format.json { render :json => #people }
#end
end
Any idea what's going on here? It seems like rails is being told to get an ID by something outside of routes.rb. I've looked everywhere I can think.
Any leads are HIGHLY appreciated.
Thanks.
EDIT:
My PeopleController begins like so:
before_filter :authenticate_user!, :except => []
filter_resource_access
respond_to :html, :js, :json
Per the discussion on your questions, the cause is a before/around filter interfering rather than an issue with your specific action. Your application is searching for a User, so it may be authentication-related.
Are you sure this goes in Control, and not in Model? Rails doesn't want Model stuff in Control.

rails routes with flash

I fixed RoutingError in rails 3 using this link. I wanted to redirect users to root page so I added:
match '*a', :to => 'homes#index'
to my routes.rb.
Question is: can I define flash[:error] message in this 'match' line to be displayed on target page?
Regards,
Mateusz
This is similar to Redirect and raise flash message when catch-all in routes
But I did run into this problem and it was giving me an issue because I was using MATCH and when I used GET, the alert wouldn't flash. Eventually I found a working solution using the thread above and applying GET in another manner.
match '*path' => redirect{ |p, req| req.flash[:alert] = "The page you requested is not valid."; '/' }, via: [:get]
This is what I ultimately came up with, via: [:get] being key to making everything work.
And remember to place such code at the end of your routes.rb

Get Rails3 to Load Different View

I'm working on a Rails3 app that has a Pages controller, and two pages: pages#main and pages#status. The main page has a link which, when clicked, goes to status. The user already has profile information, and if part of that profile information is not present, I want status to redirect to main. I'm getting a mysterious double-redirect though, that I can't solve. Here's the pages controller:
def main
#current_user = current_user
end
def status
#current_user = current_user
if #current_user.address.blank?
redirect_to :action => "main" and return
end
end
Everything works swimmingly as long as the condition isn't met, but as soon as it is, I get the error:
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".
Indeed, redirect_to is called twice (same line, according to the trace; not sure why). I'm wondering whether it is a routes problem. Here is routes.rb:
match '/main', :to => 'pages#main'
match '/status', :to => 'pages#status'
Any suggestions would be greatly appreciated.
Here is the development log:
Started GET "/status" for 127.0.0.1 at Wed Nov 03 21:28:15 -0700 2010
Processing by PagesController#status as HTML
User Load (0.3ms) SELECT "users".* FROM "users" WHERE ("users"."id" = 3) LIMIT 1
Before redirect
Before redirect
Redirected to
Redirected to
Completed in 32ms
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/pages_controller.rb:15:in `status'
app/controllers/pages_controller.rb:15:in `status'
Trying to solve the problem, I've added two debugging lines to the status method, in the hopes that it will provide some clue:
logger.debug "Before redirect"
redirect_to :action => "main" and return
logger.debug "After redirect"
So, the "Before redirect" lines are hit before we get to "Redirected to". Then "Redirected to" appears twice with no target. Incidentally, this happens with or without "and return" on the redirect line. I'm really not sure what's going on.
Also, interestingly, I added a debug line to the main method. It is never triggered.
Rav, can you paste the development log for this request? Specifically, does the first request for /status result in a redirect to /main, or does it fail with the above error?
Specifically, look in log/development.log for the most recent request block or blocks.