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 theManageMySchool::GradesController
file. This is the code in theapp/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 aRemoteAlias
set asGrade
). In theconfig/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 P开发者_运维问答aperclip::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.
精彩评论