提问人:kael 提问时间:4/18/2015 更新时间:4/20/2015 访问量:684
如何在 rails 模型中验证后插入自定义值
How to insert custom value after validation in rails model
问:
这真的很难找到有关的信息。关键是,我有一个 Rails 3.2 应用程序,它访问一个 MySQL 数据库表,其列类型为 。如果没有非原生代码,rails 不知道如何解释这一点,这很好,因为我只在内部数据库查询中使用它。POINT
然而,问题在于它被强制转换为整数,如果为空,则强制为 null。MySQL不允许此字段为null,因为它上面有一个索引,并且整数无效,因此这实际上意味着我无法通过rails创建新记录。
我一直在寻找一种在插入数据库之前更改值的方法,但我只是在我的轨道上不够亮起,无法将其拉下来。到目前为止,我已经尝试了以下方法:
...
after_validation :set_geopoint_blank
def set_geopoint_blank
raw_write_attribute(:geopoint, '') if geopoint.blank?
#this results in NULL value in INSERT statement
end
---------------------------
#thing_controller.rb
...
def create
@thing = Thing.new
@thing.geopoint = 'GeomFromText("POINT(' + lat + ' ' + lng + ')")'
@thing.save
# This also results in NULL and an error
end
---------------------------
#thing_controller.rb
...
def create
@thing = Thing.new
@thing.geopoint = '1'
@thing.save
# This results in `1` being inserted, but fails because that's invalid spatial data.
end
对我来说,理想的情况是能够强制 rails 将字符串“GeomFromText(...)”放入它创建的 insert 语句中,但我不知道该怎么做。
等待无所不知的社区的想法和意见......
答:
0赞
kael
4/20/2015
#1
好的,我最终使用了 steve klein 评论中的第一个链接来插入原始 sql。这是我的代码最终的样子:
def create
# Create a Thing instance and assign it the POSTed values
@thing = Thing.new
@thing.assign_attributes(params[:thing], :as => :admin)
# Check to see if all the passed values are valid
if @thing.valid?
# If so, start a DB transaction
ActiveRecord::Base.transaction do
# Insert the minimum data, plus the geopoint
sql = 'INSERT INTO `things`
(`thing_name`,`thing_location`,`geopoint`)
values (
"tmp_insert",
"tmp_location",
GeomFromText("POINT(' + params[:thing][:lat].to_f.to_s + ' ' + params[:thing][:lng].to_f.to_s + ')")
)'
id = ActiveRecord::Base.connection.insert(sql)
# Then load in the newly-created Thing instance and update it's values with the passed values
@real_thing = Thing.find(id)
@real_thing.update_attributes(b, :as => :admin)
end
# Notify the user of success
flash[:message] = { :header => 'Thing successfully created!' }
redirect_to edit_admin_thing_path(@real_thing)
else
# If passed values not valid, alert and re-render form
flash[:error] = { :header => 'Oops! You\'ve got some errors:', :body => @thing.errors.full_messages.join("</p><p>").html_safe }
render 'admin/things/new'
end
end
不漂亮,但有效。
评论