I have a project with PostGIS integration through RGeo gem. Rails 4, ruby 2.1.
RGeo has standard method contains? which checks is point is located in polygon. Everything is fine in development (on MacOS X). But when I push my code to production server (Ubuntu 12.04) I have this error:
ActionView::Template::Error (Method Geometry#contains? not defined.):
app/models/address.rb:28:in `block in define_courier_area'
app/models/address.rb:28:in `define_courier_area'
The code is very simple. I just need to return an array of all CourierArea instances, where are Address coords located.
address.rb
class Address < ActiveRecord::Base
def define_courier_area # HAVE TO BE REFACTORED
arr = []
CourierArea.all.each { |ca| arr << ca if ca.poly.contains?(self.coords)}
arr.first if arr.first
end
end
I suppose, production environment can't obtain access to contains? method, which is provided by RGeo gem. How can I solve this problem? Maybe I should insert require 'some_rgeo_file'?
Problem has been solved.
RGeo uses some external libraries. For geometry calculations (distance, area, point-in-polygon) this library is GEOS. When I tried to invoke contains? RGeo was seeking for GEOS but it was not installed.
Moreover there is an RGeo method RGeo::Geos.supported? for checking GEOS availability. If it will return false, you probably has no GEOS installed or RGeo has problems with connecting with it. If it will return true – boya! you can use geometry calculation methods!
It looks like RGeo might not be installed in your production environment. Run this:
gem install rgeo
That should fix it.
Related
I have a Rails 3.2 app running on Ruby 1.9.3, and I was asked to update it to Ruby 2.1 and, later, Rails 4.1. I'm having a problem upgrading to Ruby 2.1 though:
Our company have a gem that's used by our systems and defines some global constants. The application has to overwrite these constants in development (we know it's hacky, but it's temporary until we can get our staging server back on), so I have an Initializer file that overwrites these constants. That worked fine so far, I get some warnings on the server console (warning: already initialized constant ...) but it worked.
Now, however, Rails seems to be calling my custom initializer before the gem, does anyone know of a change in Ruby 2.0 or 2.1 that may induce this change of behaviour? Note that I'm still using Rails 3.2, I just updated a few gems to make it compatible with the new Ruby.
This is how I set the constant in the initializer and gem (both files have the same name and are basically the same). The constant that needs to be overwritten is URL_PORTAL:
module Portal
module Sso
URL_PORTAL_PRODUCTION = "(URL1)"
URL_PORTAL_DEVELOPMENT = "(URL2)" # I overwrite this in the initializer
URL_PORTAL_TEST = "(URL3)"
URL_PORTAL = case Rails.env
when "production" then URL_PORTAL_PRODUCTION
when "test" then URL_PORTAL_TEST
else URL_PORTAL_DEVELOPMENT
end
end
end
You can add require 'portal/seo' (or other appropriate filename) in the begining of the file.
On a server i had an installation of the gollum wiki. It ran fine. Now I also had to install redmine on that same server. This was a big pain, as redmine refused to run with puma. I had to mess around a lot with different gems to make it work at all.
But for some reason i now get an error from gollum, whenever i try to create a new wiki page:
NoMethodError at /create/old/git-tips
undefined method `translate' for I18n:Module
The stack trace shows that the error occurs in this line of stringex:
/var/lib/gems/1.9.1/gems/stringex-2.0.5/lib/stringex/localization/backend/i18n.rb in i18n_translations_for
::I18n.translate("stringex", :locale => locale, :default => {})
So i checked the installed packages with gem list and the required version of i18n 0.6.1 is there.
Any idea, what could be wrong and how to fix this?
For reference here's the output of gem list.
This may or may not help, but I had a similar problem on a large code base where there was an application-specific I18n module (which included some custom helper methods), but this was overriding the 't' method (a shortened form of translate).
In this case I found I could force the base-level I18n module by using two colons...
::I18n.t('thing')
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
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.
Is there a way to determine what version of Ruby is running from within Rails (either on the web or through script/console)? I have Ruby 1.8.6 installed but I've also installed Ruby Enterprise Edition 1.8.7-20090928 and want to ensure that it's using the right installation.
Use this global constant:
RUBY_VERSION
Other relevant global constants include:
RUBY_PATCHLEVEL
RUBY_PLATFORM
RUBY_RELEASE_DATE
Usage example via irb session:
irb(main):001:0> RUBY_VERSION
=> "1.8.7"
Try the constant RUBY_VERSION. I use this extensively to determine whether I'm running under 1.8 or JRuby.
Also, if you're not in production mode, you can do a quick check by hitting the URL "/rails/info/properties"
Use RUBY_VERSION as mentioned by others.
You can then use Gem::Version to do version string comparison:
require 'rubygems' # Only needed for ruby pre-1.9.0 but it's safe for later versions (evaluates to false).
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('1.9.0')
extend DL::Importable
else
extend DL::Importer
end
In addition to the RUBY_VERSION constant and friends you may also want to check out Config::CONFIG. This hash contains not only the version numbers but also a ton of other useful runtime information, like the path to the binary, the hostname, ...