【问题标题】:How to insert custom value after validation in rails model如何在rails模型中验证后插入自定义值
【发布时间】:2015-06-25 11:23:09
【问题描述】:

这方面的信息真的很难找到。问题的关键在于我有一个 Rails 3.2 应用程序,它可以访问一个 MySQL 数据库表,该表的列类型为POINT。如果没有非本地代码,rails 不知道如何解释它,这很好,因为我只在内部数据库查询中使用它。

然而,问题是它被强制转换为整数,如果为空则强制为空。 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(...)' 放入它创建的插入语句中,但我不知道该怎么做。

等待无所不知的社区的想法和意见....

【问题讨论】:

标签: ruby-on-rails-3 activerecord


【解决方案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

不漂亮,但很管用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-11
    • 1970-01-01
    • 2018-10-02
    • 2012-11-20
    • 2012-03-13
    相关资源
    最近更新 更多