How can I find the controller and action from rails 3 route - ruby-on-rails-3

This is basically a rails 3 version of this question. Short of parsing it myself, how can I get the components (controller, action, parameters) from a URL string?
The method ActionController::Routing::Routes#recognize_path has been deprecated, and I can't get the one it's been replaced with to work the same way:
1.9.3p125 :019 > ActionDispatch::Routing::RouteSet.recognize_path('/accounts/new', {:method => :get})
NoMethodError: undefined method `recognize_path' for ActionDispatch::Routing::RouteSet:Class
which makes sense since it's not a static method. Looking at the source didn't enlighten me either. Any pointers would be welcome.
EDIT:
ruby 1.9.3p125 (2012-02-16 revision 34643) [x86_64-darwin11.3.0]
Rails 3.2.3

This works for me (Ruby 1.9.2, Rails 3.1.0):
Rails.application.routes.recognize_path('/accounts/new', {:method => :get})

Related

Rails 3 inherited_resources ignores 'defaults' setting

I'm using Inherited resources for my controllers. And now i have model:
class Sms < ActiveRecord::Base
end
And i want controller for it, where i make defaults:
class Admin::SmsesController < Admin::InheritedResources
defaults :resource_class => Sms,
:collection_name => 'smses',
:instance_name => 'sms'
end
but i can not understand, why it still trying to get "Smse" model:
NameError in Admin::SmsesController#index
uninitialized constant Smse
Pls help.
The problem is that Rails doesn't know that the plural of Sms is Smses. If you go to the Rails console you should see that:
> "Sms".pluralize
=> "Sms"
> "Smses".singularize
=> "Smse"
When faced with a plural it doesn't recognise, singularize just truncates the final "s", which is why your app is looking for a nonexistent Smse model.
You will save yourself a lot of headaches by configuring Rails to pluralize/singularize your models correctly. In the file config\initializers\inflections.rb you should find some examples of how to do this. What you want is:
ActiveSupport::Inflector.inflections do |inflect|
inflect.irregular 'sms', 'smses'
end
Then I don't think you should need to put the defaults option in there at all - it should all work out of the box.

Dynamic attribute-based finders with Active Record RoR, Model.find_by_ does not work

I am a newby with RoR,
Environment : Rails 3.09 and ruby 1.9.2p290 installed on leopard
I am following carefully the tutorial of Michael hartl (http://ruby.railstutorial.org/).
At the chapter 7, with the console we should test this code :
$ rails console --sandbox
>> User.create!(:nom => "Michael Hartl", :email => "mhartl#example.com",
?> :password => "foobar", :password_confirmation => "foobar")
>> user = User.find_by_email("mhartl#example.com")
>> user.has_password?("foobar")
=> true
My problem is with the use of the attribute based finders , find_by_(the name of the attribute). In my example find_by_email.
Actually, rails doesn't seem to accept find_by_ as a method. Still with the example above, at the line user.has_password?("foobar") rails returns the error :
NoMethodError: undefined method. The method has_password? is well defined in my model.
I have checked the doc of the api of rails 3.0.9, and if I use this way :
>> user = User.where(:email => "mhartl#example.com")
then it works....
So I am wondering why I can't use the method find_by_ ? Other find methods work ex: find.first, find.last, etc..
Thank you to help me
fabien
Actually the finder works within the model file but not within the console (development environment).
bizarre
fabien

rails3-amf - to_amf method not found on ActiveRecord objects

I am using the rails3-amf gem by warhammerkid in my Rails 3 / Flex 4 project.
AFAIK, I have correctly followed the "Getting Started" instructions from the GitHub page.
I have added the gem lines to my Gemfile.
I have installed the gems using bundle install.
From my Flex application, I will be making the RemoteObject call to the index action in the ManageMySchool::GradesController file. This is the code in the app/controllers/manage_my_school/grades_controller.rb file:
class ManageMySchool::GradesController < ApplicationController
respond_to :html, :amf
def index
#grade = Grade.first
respond_with(#grade) do |format|
format.amf { render :amf => #grade.to_amf }
end
end
end
The name of the model which is to be serialized is called Grade in both the Rails project (app/models/Grade.rb) and the Flex project (Grade.as with a RemoteAlias set as Grade). In the config/application.rb file, I have done the class mapping this way:
config.rails3amf.class_mapping do |m|
m.map :as => 'Grade', :ruby => 'Grade'
end
And I have done a parameter mapping this way:
config.rails3amf.map_params :controller => 'ManageMySchool::GradesController', :action => 'index', :params => [:authenticity_token]
Problem
Now, when I run the server and make the RemoteObject call from Flex, I get a to_amf undefined method error for the Grade model.
If I change Grade.first to Grade.all, #grade would have an array of Grades. But the undefined method error message still mentions the Grade model. This means that the to_amf method is working for the Array class but not for the ActiveRecord model.
Why is this? What am I doing wrong?
Is there something I have to do to "enable" the rails3-amf gem for ActiveRecord models?
I would appreciate any insights. Thanks!
Update
#warhammerkid: Here is the output of Grade.ancestors as seen in rails console.
ree-1.8.7-2011.03 :006 > puts Grade.ancestors
Grade
ActiveRecord::Base
Paperclip::CallbackCompatability::Rails3::Running
Paperclip::CallbackCompatability::Rails3
Paperclip::Glue CanCan::ModelAdditions
Authlogic::ActsAsAuthentic::ValidationsScope
Authlogic::ActsAsAuthentic::SingleAccessToken
Authlogic::ActsAsAuthentic::SessionMaintenance
Authlogic::ActsAsAuthentic::RestfulAuthentication::InstanceMethods
Authlogic::ActsAsAuthentic::RestfulAuthentication
Authlogic::ActsAsAuthentic::PersistenceToken
Authlogic::ActsAsAuthentic::PerishableToken
Authlogic::ActsAsAuthentic::Password
Authlogic::ActsAsAuthentic::MagicColumns
Authlogic::ActsAsAuthentic::Login
Authlogic::ActsAsAuthentic::LoggedInStatus
Authlogic::ActsAsAuthentic::Email
Authlogic::ActsAsAuthentic::Base
ActiveRecord::Aggregations
ActiveRecord::Transactions
ActiveRecord::Reflection
ActiveRecord::Serialization
ActiveModel::Serializers::Xml
ActiveModel::Serializers::JSON
ActiveModel::Serialization
ActiveRecord::AutosaveAssociation
ActiveRecord::NestedAttributes
ActiveRecord::Associations
ActiveRecord::AssociationPreload
ActiveRecord::NamedScope
ActiveModel::Validations::Callbacks
ActiveRecord::Callbacks
ActiveModel::Observing
ActiveRecord::Timestamp
ActiveModel::MassAssignmentSecurity
ActiveRecord::AttributeMethods::Dirty
ActiveModel::Dirty
ActiveRecord::AttributeMethods::TimeZoneConversion
ActiveRecord::AttributeMethods::PrimaryKey
ActiveRecord::AttributeMethods::Read
ActiveRecord::AttributeMethods::Write
ActiveRecord::AttributeMethods::BeforeTypeCast
#<Module:0x1028356f0> ActiveRecord::AttributeMethods::Query
ActiveRecord::AttributeMethods
ActiveModel::AttributeMethods
ActiveRecord::Locking::Optimistic
ActiveRecord::Locking::Pessimistic
ActiveRecord::Validations
ActiveModel::Validations::HelperMethods
ActiveModel::Validations
ActiveSupport::Callbacks
ActiveModel::Conversion
ActiveRecord::Persistence Object
PP::ObjectMixin Base64::Deprecated
Base64
ActiveSupport::Dependencies::Loadable
Kernel
Note that only ActiveModel::Serialization is there. No mention of Rails3AMF.
Does this mean I have to do something special to load the Rails3AMF module for the ActiveRecord models?
I am using Rails 3.0.5 with the latest version of ree. The gems are all contained in a gemset managed using rvm.
Update 2
If I remove the to_amf in the render :amf line, then I get the following error:
Grade Load (0.3ms) SELECT `grades`.* FROM `grades` LIMIT 1
Completed 200 OK in 195ms (Views: 0.1ms | ActiveRecord: 0.8ms)
Sending back AMF
NoMethodError (You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.last):
Rendered /Users/anjan/.rvm/gems/ree-1.8.7-2011.03#rb/gems/actionpack-3.0.5/lib/> > action_dispatch/middleware/templates/rescues/_trace.erb (1.1ms)
Rendered /Users/anjan/.rvm/gems/ree-1.8.7-2011.03#rb/gems/actionpack-3.0.5/lib/> > action_dispatch/middleware/templates/rescues/_request_and_response.erb (2.8ms)
Rendered /Users/anjan/.rvm/gems/ree-1.8.7-2011.03#rb/gems/actionpack-3.0.5/lib/> > action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (13.6ms)
Started POST "/amf" for 127.0.0.1 at Fri Apr 15 17:03:34 +0530 2011
Sending back AMF
Update 3
If I manually add the line include Rails3AMF::Serialization at the top of the Grade.rb model file, then it all works. So, does this mean that I have to put this line in all my models?
I see that this is already being done in line numbers 40 - 42 in the lib/rails3-amf/serialization.rb file of the gem:
# Hook into any object that includes ActiveModel::Serialization
module ActiveModel::Serialization
include Rails3AMF::Serialization
end
Why isn't this working? Should I force-load the gem when my application initializes or something?
Thanks!
Update 4 - Solved by this workaround
Okay, I just ended up adding this code block in an initializer:
class ActiveRecord::Base
include Rails3AMF::Serialization
end
And it is working.
#warhammerkid - Thanks for the help.
Rails3AMF::Serialization, the module that adds the to_amf method, is included in ActiveModel::Serialization when Rails3-AMF loads. If it's somehow not being included even though the code is running and ActiveModel::Serialization is one of your model's ancestors, then the simplest solution is just to add "include Rails3AMF::Serialization" at the top of your model implementation. I've never tried gem sets before, but it might be an issue with them, as everything works correctly using Bundler.
As an aside, feel free to post a bug to https://github.com/warhammerkid/rails3-amf/issues.

RSpec: simplest test fails with error: Expected block to return true value

I'm testing the waters with Rails and I'm stuck with this simple test:
I have this code in spec/routing/routing_spec.rb
require 'spec_helper'
describe "Accessing the root domain" do
it "should route to home#index" do
{ :get => '/' }.
should route_to(:controller => 'home', :action=>'index')
end
end
This fails with the following error:
Failure/Error: { :get => '/' }.
Expected block to return true value.
# ./spec/routing/routing_spec.rb:7:in `block (3 levels) in <top (required)>'
What's wrong in my code?
I ran into this opaque error message as well with Rails 3 and Ruby 1.9.2. The reason in my case was that I was using an old version of minitest that ships with Ruby, and in that version the assert_block method (invoked by assert_recognizes in ActionDispatch::Assertions::RoutingAssertions) does not display the error message (how the routing params didn't match). The fix for me was to add minitest to my Gemfile and install it via bundler:
group :test do
gem "minitest", ">= 2.6.1" # The minitest version that ships with Ruby is old and has bugs
end
I would then get a more understandable error message:
The recognized options <{"action"=>"index",
"controller"=>"publish/product_versions",
"product_id"=>"ipad_app"}> did not match <{"controller"=>"publish/product_versions",
"action"=>"indexx",
"product_id"=>"ipad_app"}>, difference: <{"action"=>"indexx"}>.
Expected block to return true value.
This seems like it should work, so my guess would be that there is a configuration problem. Difficult to know what it is, though, without seeing more of the app. Also, the failure says it happens on line 7, but it references line 5 in the code above, so there might be something else in the file that is gumming up the works.
Also, the error message is confusing because the expectation is written on two lines. If you wrote it on one line, you'd see the whole statement. Not that that would help narrow down this problem, other than to help you understand that it's not trying to treat { :get => '/' } as a block.
HTH,
David
This happened with me because my controller rendered the wrong view. I fixed the logic of my controller method and everything worked fine.

rails3 unscoped within the model gets overriden by default_scope

I have this model
User.rb
default_scope :order => 'users.created_at DESC'
and
scope :ranking, lambda { unscoped { order('users.ranking DESC') }}
and still I get a to_sql that includes ORDER BY users.created_at DESC, users.ranking DESC...
can someone explain why?
I really don't want to have to call unscoped from every controller i'll be using this model in.
Thanks!
As you're discovering, default_scope is often more trouble than it's worth. If you're wanting to stick with it, you could use reorder to ignore the previous order:
scope :ranking, reorder("ranking DESC")
Not sure why #TimPost deleted my answer but I'm using rails 3.0.5 and ruby 1.9.2 for a project and when I used reorder(which works btw) it says this in the log
DEPRECATION WARNING: reorder is deprecated. Please use except(:order).order(...) instead. (called from <class:Item>
So I don't think it is fair my answer was deleted and I got dinged for a crappy response