Using Rails 3 with Geokit-rails3 location gem - ruby-on-rails-3

I am trying to use the geokit-rails3 gem for geolocation information in a rails application. I have a simple model:
class Location < ActiveRecord::Base
def lookup_ip_information(post_ip)
ip = post_ip
location = IpGeocoder.geocode(ip)
puts location.full_address
lat = location.lat
lng = location.lng
end
end
When I call this method with request.remote_ip from my controller, it's throwing an error: uninitialized constant Location::IpGeocoder

I just had this issue and resolved it by entering the full
Geokit::Geocoders::IpGeocoder.geocode(request.remote_ip)
and that seemed to solve it for me.

Had the same issue and couldn't get IpGeocoder to work in Rails3 with above suggestions. Dug into the Rails3 source code for the gem. Looks like an easy way to work around this is use the Geokit MultiGeocoder method for Rails 3.
Example:
loc = Geokit::Geocoders::MultiGeocoder.geocode(remote.request_ip)
Don't forget to set up MultiGeocoder correctly in your initializer - geokit_config.rb
Geokit::Geocoders::provider_order = [:google,:us]

Related

Time methods in rails

I see in http://api.rubyonrails.org/ rails 3.2.12 that the class Time has a set of methods like:
beginning_of_day,
beginning_of_hour,
beginning_of_month,
beginning_of_quarter,
beginning_of_week,
beginning_of_year
When I try something like t = Time.beginning_of_hour in the rails console, I get an undefined method error.
How can I experiment with these methods?
It is Date.today. There is Time.now if you want to use that.

Cannot find FakeInput

I am trying add a fake input to simple_form using the following suggestion (rails simple_form fields not related to the model), but it does not work for me.
This is my HAML code for adding a fake input field.
= f.input :agrees_to_terms, :as => :fake
I put the following class in app/inputs/fake_input.rb
class FakeInput < SimpleForm::Inputs::StringInput
# This method only create a basic input without reading any value from object
def input
template.text_field_tag(attribute_name, nil, input_html_options)
end
end
I get the following runtime error
No input found for fake
I have two initializers that were generated by Rails Composer: simple_form.rb and simple_form_bootstrap.rb
How can I make Rails find my FakeInput class?
I had the same issue, and a server restart resolved it.

Troubles with Rails 3 and classes in nested directories

I have a rails project that I inherited. I'm working on upgrading it from rails 2 to rails 3. I'm at 3.0.15 right now, working my way up to 3.2. In the app directory there is a support folder with classes in it. Like so:
app/
support/
sweeper.rb
grouped_list/
item.rb
list.rb
item.rb looks like this:
class Support::GroupedList::Item
attr_accessor :name, :count, :link
def initialize(name, count, link)
#name = name
#count = count
#link = link
end
end
In one of the controllers the Items class is called like this:
Support::GroupedList::Item.new name, count, link
when I try and load a page I get the error:
uninitialized constant ApplicationController::Support
My first thought was that the paths where not in the autoload so I added
config.autoload_paths += %W(#{config.root}/app/support #{config.root}/app/support/grouped_list)
in my application.rb but that didn't change anything. After looking around for examples I found that people where creating empty module in their directory structure so I created a support.rb file in the support folder that looks like this:
module Support
end
Now my error changes to
uninitialized constant Support::GroupedList
Hey! That's interesting, I don't understand why it changed but its progress right? So I add a grouped_list.rb file in the grouped_list directory. It looks like this:
module Support::GroupedList
end
But then I get
Expected ***/app/support/grouped_list/grouped_list.rb to define GroupedList
Ugh! so I change it to:
module GroupedList
end
But then I'm back to:
uninitialized constant Support::GroupedList
So clearly there is some fundamental knowledge I'm missing about loading classes in modules. This structure worked in rails 2 but breaks in rails 3.0.15. I'd really like to understand so if anyone can help me out I'd really appreciate it.
class GroupedList::Item
attr_accessor :name, :count, :link
def initialize(name, count, link)
#name = name
#count = count
#link = link
end
end
This should work. Then in your controller:
GroupedList::Item.new name, count, link
Also remember to restart your rails server/console, after you make these changes.

Adding to Rails autoload_path from Gem

I want to write a gem that adds a app/services directory to a Rails application.
Since I want to add it from within the Gem i came up with this solution:
class Railtie < ::Rails::Railtie
config.after_initialize do |app|
::Rails.logger.info "adding #{ActiveService::Configuration.path} to autoload_path"
app.config.autoload_paths = [ActiveService::Configuration.path] + app.config.autoload_paths
end
end
The problem is that config.autoload_path is a frozen array, so that modifing it seems not to be a good idea.
Any suggestions of how this could be achieved in a better way?
config.autoload_paths is frozen inside the :set_autload_paths initializer. The Array is passed on to ActiveSupport::Dependencies.autoload_paths, so modifying the original Array would not make much sense. Therefore it's frozen.
You should be able to hook into :before => :set_autoload_paths and extend config.autoload_paths before it's passed and frozen:
class Railtie < ::Rails::Railtie
initializer 'activeservice.autoload', :before => :set_autoload_paths do |app|
app.config.autoload_paths << ActiveService::Configuration.path
end
end
Documentation about initializer hooks can be found at guides.rubyonrails.org/initialization.html
First, all directories under app/* are already in the load path since Rails 3.0. In any case, if you want to do it, you should use the paths api instead. Example from Rails source code:
https://github.com/rails/rails/blob/master/railties/lib/rails/engine/configuration.rb#L42

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.