`ActiveModel::MissingAttributeError` 最近添加的列

问题描述 投票:0回答:1

注意: 关于 SO 有很多旧的 Q/A,其中人们要么 (1) 尝试设置关联的

has_one_id
列,或者 (2) 设置计数器缓存的
count
列,或者(3) 在测试期间,当测试数据库尚未运行迁移时设置它。这些不是我的问题。

在我的 Rails 7.1.4 应用程序中,我刚刚向我的

locations
表添加了一个迁移,该表添加了
box_area
列。保存时,该列的值将根据其他列的值计算。

但是 ActiveModel 不允许我向该列保存任何值。我不明白为什么。我已经运行了迁移。该列显示在 schema.rb 中。

根据 mysql,这是数据库表的当前状态:

mysql> SHOW COLUMNS FROM locations;
+-----------------+----------------+------+-----+---------+----------------+
| Field           | Type           | Null | Key | Default | Extra          |
+-----------------+----------------+------+-----+---------+----------------+
| id              | int            | NO   | PRI | NULL    | auto_increment |
| created_at      | datetime       | YES  |     | NULL    |                |
| updated_at      | datetime       | YES  |     | NULL    |                |
| user_id         | int            | YES  |     | NULL    |                |
| north           | float          | YES  |     | NULL    |                |
| south           | float          | YES  |     | NULL    |                |
| west            | float          | YES  |     | NULL    |                |
| east            | float          | YES  |     | NULL    |                |
| name            | varchar(1024)  | YES  |     | NULL    |                |
| box_area        | decimal(21,10) | YES  |     | NULL    |                |
+-----------------+----------------+------+-----+---------+----------------+

以下是 ActiveRecord 关于该列的说明:

irb(main):003> Location.columns
...
#<ActiveRecord::ConnectionAdapters::MySQL::Column:0x0000000108870d30
  @collation=nil,
  @comment=nil,
  @default=nil,
  @default_function=nil,
  @name="box_area",
  @null=true,
  @sql_type_metadata=#<ActiveRecord::ConnectionAdapters::SqlTypeMetadata:0x0000000108870fb0 @limit=nil, @precision=21, @scale=10, @sql_type="decimal(21,10)", @type=:decimal>>]

要分配值,我在模型上使用

before_save
回调:

  before_save :calculate_box_area

  def calculate_box_area
    self.box_area = calculate_area
  end

  def calculate_area
    # math 
  end

如果我在回调中中断,我可以看到

self.box_area
=> 0.2428601638665e3

但是保存时出现错误。

can't write unknown attribute `box_area` (ActiveModel::MissingAttributeError)

我尝试过这个,在

rails console

irb(main):001> loc = Location.new(north: 4, south: 3, east: 5, west: 4, user_id: 1, name: "glade")
irb(main):002> loc.save
(irb):9:in `<main>: can't write unknown attribute `box_area` (ActiveModel::MissingAttributeError)`

irb(main):010> loc.attributes
=> 
{"id"=>nil,
 "created_at"=>Sun, 29 Sep 2024 04:48:58.000000000 EDT -04:00,
 "updated_at"=>Sun, 29 Sep 2024 04:48:58.000000000 EDT -04:00,
 "user_id"=>1,
 "north"=>4.0,
 "south"=>3.0,
 "west"=>4.0,
 "east"=>5.0,
 "name"=>"glade",
 "box_area"=>0.123449675887591e5}

为什么?这是怎么回事?

ruby-on-rails activerecord
1个回答
0
投票

我不确定在 mysql 中我们需要填写完整的属性。如果添加

box_area: 0.0
有效吗?

Location.new(北:4,南:3,东:5,西:4,user_id:1,名称:“空地”,box_area:0.0)

如果是我的话。我会这样处理

  1. 在位置表中。可以默认
    box_area
 change_column(:locations, :box_area, :float, default: 0.0)
  1. 模型中的默认值
class Location < ActiveRecord::Base
    after_initialize :init

    def init
      self.box_area  ||= 0.0
    end
  end   

如果有人有更好的解决方案,请告诉我。谢谢

© www.soinside.com 2019 - 2024. All rights reserved.