好像我的before_destroy方法在本地成功运行,但在Heroku上却没有。
在用户删除部件之前,应用程序会检查WorkOrder中是否存在相应的行项目,如果是,则禁止该操作。
现在,如果我尝试销毁控制台中的某个部件,则会遵循before_destroy方法,并且日志会显示回滚(与本地删除部件时相同)。如果我删除控制台中的某个部件,则会删除该部件而不会出现错误。对于我没有经验的眼睛,似乎部件在Heroku上被删除,而不是被销毁,即使日志说正在调用#destroy。
Delete函数是rails生成的,看起来像这样
<%= link_to t('.destroy', :default => t("helpers.links.destroy")), part_path(part), :method => :delete
。
我知道删除和销毁在has_many,:through关系方面有区别,但我不确定是否在这里播放。
感谢任何帮助。谢谢!
Part.rb
class Part < ActiveRecord::Base
has_many :line_items
before_destroy :ensure_not_referenced_by_line_item #works fine locally
def ensure_not_referenced_by_line_item
if ( LineItem.any? { |li| li.part_id == self.partnum } )
errors.add(:base, "Cannot delete this part, as it is referenced in a work order.")
return false
end
end
end
LineItem.rb
class LineItem < ActiveRecord::Base
belongs_to :part
WorkOrder.rb
class WorkOrder < ActiveRecord::Base
has_many :line_items, dependent: :destroy
has_many :parts, :through => :line_items
本地Webrick日志
Started DELETE "/parts/2" for 127.0.0.1 at 2014-03-08 18:36:14 -0500
Processing by PartsController#destroy as HTML
Part Load (0.2ms) SELECT "parts".* FROM "parts" WHERE "parts"."id" = $1 ORDER BY partnum ASC LIMIT 1 [["id", "2"]]
(0.1ms) BEGIN
LineItem Load (0.2ms) SELECT "line_items".* FROM "line_items"
(0.1ms) ROLLBACK
Redirected to http://localhost:3000/parts
Heroku Logs
: Started DELETE "/parts/25" for x.x.x at 2014-03-08 23:38:45 +0000
: Processing by PartsController#destroy as HTML
: Processing by PartsController#destroy as HTML
: Part Load (46.6ms) SELECT "parts".* FROM "parts" WHERE "parts"."id" = $1 ORDER BY partnum ASC LIMIT 1 [["id", "25"]]
: Part Load (46.6ms) SELECT "parts".* FROM "parts" WHERE "parts"."id" = $1 ORDER BY partnum ASC LIMIT 1 [["id", "25"]]
: (6.9ms) BEGIN
: (6.9ms) BEGIN
: LineItem Load (4.3ms) SELECT "line_items".* FROM "line_items"
: LineItem Load (4.3ms) SELECT "line_items".* FROM "line_items"
: SQL (2.1ms) DELETE FROM "parts" WHERE "parts"."id" = $1 [["id", 25]]
: SQL (2.1ms) DELETE FROM "parts" WHERE "parts"."id" = $1 [["id", 25]]
: (3.7ms) COMMIT
: (3.7ms) COMMIT
: Redirected to ....herokuapp.com/parts
答案 0 :(得分:1)
默认情况下,has_many :line_items
字段上的Part.id
匹配,但您检查是否引用了某些内容的测试是检查partnum字段。你确定id和partnum总是一样吗?我怀疑它们不在Heroku中存储的数据中。
此外,您的验证不符合您的想法。
您的Parts#ensure_not_referenced_by_line_item
函数将始终返回false。 if语句将为true,在这种情况下显式返回false,或if语句将为false,在这种情况下函数隐式返回false(函数的值是最后一个操作的值,即if声明,这是假的。)
更好的写作方式是
def ensure_not_referenced_by_line_item
not(LineItem.exists?(part_id: self.id))
end
请注意,在这次重写中,我引用的是self.id,而不是self.partnum