Geokit and rails 3 - ruby-on-rails

I am using the geokit gem and plugin with rails 3. It seems there is a known issue with them, which can be seen here http://github.com/andre/geokit-rails/issues#issue/15
Now, I tried to follow the solution provided at the bottom. I pasted that function definition, at the end of the file, just above acts_as_mapable, and just after the first time it was called, but nothing happened each time.
Any idea what else can be done?
Thanks

I ran into similar problems upgrading my app to rails 3. I'm still using Geokit for geocoding but Active Record scopes for distance based database queries. It's pretty convenient, and you still get all of the Active Record 3 goodness. Here's an example from my User model:
scope :near, lambda{ |*args|
origin = *args.first[:origin]
if (origin).is_a?(Array)
origin_lat, origin_lng = origin
else
origin_lat, origin_lng = origin.lat, origin.lng
end
origin_lat, origin_lng = deg2rad(origin_lat), deg2rad(origin_lng)
within = *args.first[:within]
{
:conditions => %(
(ACOS(COS(#{origin_lat})*COS(#{origin_lng})*COS(RADIANS(users.lat))*COS(RADIANS(users.lng))+
COS(#{origin_lat})*SIN(#{origin_lng})*COS(RADIANS(users.lat))*SIN(RADIANS(users.lng))+
SIN(#{origin_lat})*SIN(RADIANS(users.lat)))*3963) <= #{within}
),
:select => %( users.*,
(ACOS(COS(#{origin_lat})*COS(#{origin_lng})*COS(RADIANS(users.lat))*COS(RADIANS(users.lng))+
COS(#{origin_lat})*SIN(#{origin_lng})*COS(RADIANS(users.lat))*SIN(RADIANS(users.lng))+
SIN(#{origin_lat})*SIN(RADIANS(users.lat)))*3963) AS distance
)
}
}
Here's a blog post with a little more detail on the subject: http://stcorbett.com/code/distance-queries-with-rails-3-without-geokit/

jlecour's port to rails 3 should solve any issues you were having last year.
Make sure you're using mysql or postgres if you're doing distance calculations.

After trouble installing the geokit-rails3 gem on Rails 3.1 I moved to the geocoder gem. It has distance calculation as well (be sure to not forget the s in #your_model.nearby*s*(5)). There is also a Railscast.

Here is port of geokit to rails 3, incomplete through:
https://github.com/jlecour/geokit-rails3

For those still having trouble with geokit, i moved on to using mongodb... which has inbuilt distance search n all...

Hey Amit, Not sure if you sorted this out yet but I'll tell you what I did just in case.
I forked andre's geokit-rails source and then cloned it locally and added the code from this gist at line 34 of lib/geokit-rails/acts-as-mappable.rb, just after the line that reads module ClassMethods # :nodoc:.
Then I commited those changes back to my forked repo on github and used my fork to install the source as a plugin to my rails 3 app. That seemed to work straight away, but make sure you have the acts_as_mappable line added to whatever model you are wanting to do distance calculations on and make sure you have two float columns on that db named :lat and :lng.

Related

Updating a Rails model's attributes through mongoid using normal persistence methods

I have been chasing an issue down for a while now, and still cannot figure out what's happening. I am unable to edit documents made from my gem through normal persistence methods, like update or even just editing attributes and calling save.
For example, calling:
Scram::Policy.where(id: a.id).first.update!(priority: 12345)
Will not work at all (there are no errors, but the document has not updated). But the following will work fine:
Scram::Policy.collection.find( { "_id" => a.id } ).update_one( { "$set" => {"priority" => 12345}})
I am not sure what I'm doing wrong. Calling update and save on any other model works fine. The document in question is from my gem: https://github.com/skreem/scram/blob/master/lib/scram/app/models/policy.rb
I cannot edit its embedded documents either (targets). I have tried removing the store_in macro, and specifying exactly what class to use using inverse_of and class_name in a fake app to reimplement these classes: https://github.com/skreem/scram-implementation/blob/master/lib/scram/lib/scram/app/models/policy.rb
I've tried reimplementing the entire gem into a clean fake rails application: https://github.com/skreem/scram-implementation
Running these in rails console demonstrates how updating does not work:
https://gist.github.com/skreem/c70f9ddcc269e78015dd31c92917fafa
Is this an issue with mongoid concerning embedded documents, or is there some small intricacy I am missing in my code?
EDIT:
The issue continues if you run irb from the root of my gem (scram) and then run the following:
require "scram.rb"
Mongoid.load!('./spec/config/mongoid.yml', :test)
Scram::Policy.first.update!(priority: 32) #=> doesn't update the document at all
Scram::Policy.where(id: "58af256f366a3536f0d54a61").update(priority: 322) #=> works just fine
Oddly enough, the following doesn't work:
Scram::Policy.where(id: "58af256f366a3536f0d54a61").first.update(priority: 322)
It seems like first isn't retrieving what I want. Doing an equality comparison shows that the first document is equal to the first returned by the where query.
Well. As it turns out, you cannot call a field collection_name or else mongoid will ensure bad things happen to you. Just renaming the field solved all my issues. Here's the code within mongoid that was responsible for the collision: https://github.com/mongodb/mongoid/blob/master/lib/mongoid/persistence_context.rb#L82
Here's the commit within my gem that fixed my issue: https://github.com/skreem/scram/commit/25995e955c235b24ac86d389dca59996fc60d822
Edit:
Make sure to update your Mongoid version if you have dealt with this issue and did not get any warnings! After creating an issue on the mongoid issue tracker, PersistenceContext was added to a list of prohibited methods. Now, attempting to use collection_name or collection as a field will cause mongoid to spit out a couple of warnings.
Fix commit: https://github.com/mongodb/mongoid/commit/6831518193321d2cb1642512432a19ec91f4b56d

Convert an ActiveRecord column to PostGIS Point

My setup:
Ruby 2.0.0
Rails 3.2.12
most recent pg gem
most recent activerecord-postgis-adapter gem
most recent rgeo-geojson gem
Postgres 9.1.6
PostGIS 2
I've asked something similar a few days ago. (Need to convert a Boolean from Postgres (== String) to a Ruby Boolean). There I had to convert a value from a custom select to boolean. This was pretty straight forward, by just adding this to my model:
def value_name
ActiveRecord::ConnectionAdapters::Column.value_to_boolean(self[:value_name])
end
But now I receive a value of type Point (which is a type from PostGIS). Its string representation in database looks like "0101000000EE7C3F355EF24F4019390B7BDA011940", but it has to become a (I think) RGeo::Feature::Point or maybe RGeo::Geos::CAPIPointImpl ?!
Now I looked at ActiveRecord::ConnectionAdapters::Column (http://rubydoc.info/docs/rails/ActiveRecord/ConnectionAdapters/Column), I can only find value_to_boolean and value_to_decimal.
Then I recognized that there is also ActiveRecord::ConnectionAdapters::PostgreSQLColumn (http://rubydoc.info/docs/rails/ActiveRecord/ConnectionAdapters/PostgreSQLColumn), but it doesn't seem to have any useful methods.
Thank you!
Try something like that :
def value_name
point_regex = /POINT \(([0-9]*\.[0-9]*) ([0-9]*\.[0-9]*)\)/
match_data = self[:value_name].match(point_regex)
match_data[1], match_data[2]
end
It will return a couple of value [x, y] representing your point.
You have to do the inverse, i.e. define a value_name=(x,y).
I found a solution (searched for rgeo and parse):
def my_value
a = RGeo::WKRep::WKBParser.new
a.parse(self[:my_value])
end
I just need to know if it's the right way. Coming from the Java world, I read it like this:
For every(!) my_value: Create a new instance of WKBParser
If that's the case: How can I create just one instance of it and reuse it every time the method is called?
Or in more detail: How does the automatic parser handle this? Where does it get called?
I think it get's created here: https://github.com/dazuma/activerecord-postgis-adapter/blob/master/lib/active_record/connection_adapters/postgis_adapter/spatial_column.rb (Line 179 and 181)
But how can I reuse this in my model?
Background information: The parser automatically works for real table columns, but my column gets created within the query.
Found the right way:
def my_value
RGeo::Geos.factory.parse_wkb(self[:my_value])
end
:)
Yep, postgis adapter really works, and provides much more elegant solution.
In my Gemfile:
gem 'rails', '3.2.12'
gem 'pg'
gem 'rgeo-activerecord'
gem 'activerecord-postgis-adapter'
then in the model:
class MyPoint < ActiveRecord::Base
set_rgeo_factory_for_column(:geom, RGeo::Geos.factory(srid: 4326))
attr_accessible :geom
end
to find if Geos is supported in your RGeo installation:
>> RGeo::Geos::supported?
true
And that's what you get - model's attribute geom which is in this case RGeo::Geos::CAPIPointImpl (will vary depending on factory class). To get this factory working you need to have Geos with development files installed before installing RGeo. Doesn't have to be Geos factory and 4326, RGeo has factories implemented in pure Ruby, find your best match factory class and SRID in the docs: http://rubydoc.info/github/dazuma/rgeo/master/index

Rails model: saving works locally but not on Heroku

I have a Rails model for a Recipe.
It has an attribute, views, which counts how many times it has been viewed.
In the show action of my controller, I fetch the model object normally:
#recipe = Recipe.find(params[:id])
Then I increase the view count and save:
#recipe.views = #recipe.views + 1
#recipe.save
This works without a hitch locally, but on Heroku, the save apparently doesn't happen.
No errors are thrown.
I can run this exact same code in the rails console on Heroku, and then it works.
The only way I can get it to work, is setting
config.cache_classes = false
in environmenst/production.rb
This is obvously not what I want, but I'm stumped about how to go from here.
I'm running Rails 3.2.8, Ruby 1.9.3 on the Cedar stack, using Postgresql 9.1 in both development and on production.
FWIW to future searchers looking for their own solution, Benjamin Tan's answer (in comments) of heroku restart was what worked for me when I had a similar problem.
Copying the answer from the edited question body in order to remove this question from the "Unanswered" filter:
UPDATE: Fixed
Turns out I had a file with another older definition of the controller in the app/controllers directory.
~ answer per Azzar

Problems updating Paperclip from plugin to gem

I am apparently having a huge problem switching from the plugin version of Paperclip to the gem version in my app. It's been my impression that there should be no difference whatsoever between a plugin and a gem of a specified version. However, I'm not seeing this as an easy transition at all.
Rails 2.3.11, Ruby 1.8.7
The plugin version I am using is version 2.3.3 and was upgraded on August 2, 2010. Attempting to update this to the gem of the same version basically killed all my tests, not being able to load a factory model which did not have its attachment loaded. It appeared that validate_attachment_content_type was also attempting to validate the attachment presence, and couldn't find it, so everything just started breaking. Again, with the plugin there are no problems and I haven't had any problems in all this time we've been using it. On the other hand, this problem seems to not occur past version 2.3.4. That's a whole other set of problems.
Basically, in all versions from 2.3.4 and up I get the problem below:
can't convert nil into String
/home/joshua/.rvm/gems/ruby-1.8.7-p334#paperclip_upgrade/gems/paperclip-2.3.15/lib/paperclip/storage/s3.rb:163:in `extname'
/home/joshua/.rvm/gems/ruby-1.8.7-p334#paperclip_upgrade/gems/paperclip-2.3.15/lib/paperclip/storage/s3.rb:163:in `to_file'
/home/joshua/.rvm/gems/ruby-1.8.7-p334#paperclip_upgrade/gems/paperclip-2.3.15/lib/paperclip/attachment.rb:94:in `assign'
/home/joshua/.rvm/gems/ruby-1.8.7-p334#paperclip_upgrade/gems/paperclip-2.3.15/lib/paperclip.rb:279:in `avatar='
/home/joshua/railscamp/app/app/models/organization.rb:311:in `copy_membership'
in all my tests that access my organization model.
The apparent offending code in this case is attempting to clone a membership model from one organization to another, with the * line being the offending call.
def copy_membership(membership)
m = membership.clone
u = m.user.clone
u.organization = self
m.organization = self
begin
m.avatar = membership.avatar *
rescue RuntimeError
m.avatar = nil
end
m.user = u
m.save
m
end
Does this make any sense to anyone? Why would the plugin work, but the gem of the same version just wrecks everything?
Update: I also don't appear to have any paperclip rake tasks available. Any ideas?
As it turns out, we should have been checking whether the filename is valid or not, rather than depending on a generic runtime error for detecting avatar presence.

Integrate Mongoid and CanCan

Have somebody tried to rewrite CanCan ActiverRecordAddtions for
Mongoid http://github.com/ryanb/cancan/blob/master/lib/cancan/active_record_additions.rb
Regards,
Alexey Zakharov
I've managed to get CanCan and Mongoid (version 2) to work together pretty well on a rails 3 app. Still get some errors here and there related to conditions in the permission definition (the Ability model).
I just put the contents of this gist into a file in config/initializers:
http://gist.github.com/561639
The condition hashes are almost the same as with ActiveRecord:
# can only manage own account
can :manage, User, :_id => current_user.id
I'm still working on how to use more advanced Mongoid::Criteria conditions, but you can always use a block to do more complex conditions:
# can only manage own account
can :eat, Cake do
current_user.jobs.any?{ |job| job.title == 'Peasant'}
end
I know it's an old one, but for those who search mongoid and cancancan integration, you could try official mongoid adapter
For cacancan gem version >2.0 there's separate gem cancacan-mongoid
Bear in mind that this gem status is "in development", but still it's working pretty well and build passing

Resources