3

Let's say I have a very simple table that just has a single geometry column (point) that the user can update:

CREATE TABLE m_point (
id int(11) NOT NULL AUTO_INCREMENT,
point geometry NOT NULL,
deleted_at datetime DEFAULT NULL,
created_at datetime DEFAULT NULL,
updated_at datetime DEFAULT NULL,
PRIMARY KEY (id) )

How can I insert into this using rails, as the geometry column requires actual geometry?

I would have thought this would work:

loc = MPoint.new
loc.point = "POINT(#{params[:x]},#{params[:y]})"
loc.save!

but I get the error:

Mysql2::Error: Cannot get geometry object from data you send to the GEOMETRY field: INSERT INTO `m_point` (`point`) VALUES ('POINT(35, 10)')

as the POINT(X,Y) is seen as rails as being a string. How do I get it so that rails accepts POINT(#{params[:x]},#{params[:y]}) as an unquoted command?

Yes, it would be simple to do an INSERT, but I am wondering if there is any other way, short of installing a gem, to get this to work with rails.

2 Answers 2

1

One approach to do this would be to include a setter for the point attribute in your MPoint model, then execute manual SQL to update the column.

eg.

def set_point(x, y)
   connection.execute("UPDATE m_point SET point = POINT(#{x}, #{y}) WHERE ID = #{self.id}")
end

You could further improve it by calling it on the after_save callback on the model, and use virtual attributes in your model to use in your set_point method.

Sign up to request clarification or add additional context in comments.

2 Comments

I was considering just doing an update after the initial insert, but that defeats the purpose of trying to do it in rails. Also, would have to put in a dummy value as location is NOT NULL.
Ye if you need NOT NULL then can't do it this way. Will have to look into a gem as zetetic mentioned.
0

I wouldn't expect this to work with vanilla Rails. The GEOMETRY type is specific to MySQL if I recall correctly, and only works with spatial extensions enabled.

You might look at activerecord-mysql2spatial-adapter

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.