Reputation: 31
I have a problem in using Rails / ActiveRecord.
I want to insert record with MySQL function, for example GeomFromText('POINT(1 1)')
.
Using ActiveRecord normally, these functions are quoted automatically. I want not to quote these values.
Model.create(geo: GeomFromText('POINT(1 1)'))
this ActiveRecord statement will generate following SQL
INSERT INTO `Model` (`geo`) VALUES ('GeomFromText(\'POINT(1 1)\')')
It may be easy to use raw SQL, but I want to use ActiveRecord because my Model set several callbacks include self table.
How can use MySQL function with ActiveRecord statement?
Upvotes: 3
Views: 1483
Reputation: 303
You can't by design; this behavior is important for preventing SQL injection attacks. You would need to explicitly execute raw SQL in conjunction with ActiveRecord.
As you saw, the SQL statement gets interpolated as a string by design, which doesn't do what you want (Rails ~> 4.0):
> Country.create(name: 'LOWER("CANADA")')
=> SQL (0.3ms) INSERT INTO `Country` (`Name`) VALUES ('LOWER(\"CANADA\")')
Nor can you use the same tricks that would work for the .where
method:
> Country.create(["name = LOWER(:country)", { country: 'CANADA' }])
=> ArgumentError: When assigning attributes, you must pass a hash as an argument.
You would need to execute arbitrary SQL first to get the proper value, then make another SQL call via ActiveRecord to achieve your callback:
> Country.create( name: ActiveRecord::Base.connection.execute(%q{ SELECT LOWER('CANADA') }).first[0] )
=> (0.3ms) SELECT LOWER('CANADA')
=> SQL (0.3ms) INSERT INTO `Country` (`Name`) VALUES ('canada')
That said, it's probably cleaner to re-implement the SQL function at the application layer instead of the DB layer (unless you've got a really complex SQL function).
Upvotes: 2