为什么在我 运行 一个方法后我的 Rails 模型属性没有更新?
Why isn't my Rails model attribute updated after I run a method?
我有一个 Rails 应用程序,其中包含两个模型 - SalesOpportunity 和 Swot:
销售机会:
class SalesOpportunity < ActiveRecord::Base
has_many :swots, dependent: :destroy, inverse_of: :sales_opportunity
before_save :update_swot_score
def update_swot_score
strong = 0
weak = 0
opp = 0
threat = 0
self.swots.each do |s|
if s.strength?
strong = strong + Swot.swot_importances[s.swot_importance]
elsif s.weakness?
weak = weak + Swot.swot_importances[s.swot_importance]
elsif s.opportunity?
opp = opp + Swot.swot_importances[s.swot_importance]
elsif s.threat?
threat = threat + Swot.swot_importances[s.swot_importance]
end
end
swot_strength_score = strong - weak
swot_opp_score = opp - threat
puts swot_strength_score
puts swot_opp_score
if swot_strength_score == 0 && swot_opp_score == 0
swot_score = 0
elsif swot_strength_score > 0 && swot_opp_score >=0 || swot_strength_score = 0 && swot_opp_score > 0
swot_score = 1
elsif swot_strength_score > 0 && swot_opp_score < 0
swot_score = 2
elsif swot_strength_score <=0 && swot_opp_score < 0
swot_score = 3
elsif swot_strength_score <0 && swot_opp_score >= 0
swot_score = 4
end
puts swot_score
return swot_score
sales_opportunity.update_attributes!
end
结束
斯沃特:
class Swot < ActiveRecord::Base
belongs_to :sales_opportunity, inverse_of: :swots
validates :swot_details, presence: true
validates :sales_opportunity_id, presence: true
enum swot_type: [:strength, :weakness, :opportunity, :threat]
enum swot_importance: { minimal: 1, marginal: 2, noteworthy: 3, significant: 4, critical: 5 }
before_save :update_opportunity_score
def update_opportunity_score
sales_opportunity.update_swot_score
sales_opportunity.save
end
end
如您所见,我正在向 SalesOpportunities 添加 swot,在保存新的 Swot 时,我 运行 SalesOpportunity 模型中的 update_swot_score 方法,它遍历 swot 并计算一堆返回 swot_score 之前的值。我打算使用 swot_score 来显示每个分数的不同消息 - 但是我似乎无法在 update_swot_score 方法完成后将 swot_score 属性保存在数据库中。
我 运行 这在控制台中很好(s 被定义为我的 SalesOpportunities 之一,其中已经添加了 swot):
irb(main):014:0> s.update_swot_score
2
1
1
=> 1
这是正确的结果 - swot_strength_score 应该是 2,swot_opp_score 应该是 1,结果 swot_score 也应该是 1。但是当我然后 运行:
irb(main):015:0> s.swot_score
=> 0
如您所见,swot_score 现在为 nil(这是数据库中的默认值)。我试过使用 .save!、.save、.update_attributes,甚至尝试在方法末尾保存 sales_opportunity,但无济于事。我确定这是一个非常愚蠢的问题,但答案很明显,但我在这里做错了什么?
这是 ruby 陷阱之一。当你这样做时:
swot_score = 0
您创建了一个局部变量,您并未更改实例属性值。在你的例子中 swot_score
这样的实例属性是方法,你需要执行一个方法 swot_score=
来分配它。通过键入:
self.swot_score = 0
它会让解析器意识到你想在当前的自身对象上执行swot_score=
方法而不是创建局部变量。
我有一个 Rails 应用程序,其中包含两个模型 - SalesOpportunity 和 Swot:
销售机会:
class SalesOpportunity < ActiveRecord::Base
has_many :swots, dependent: :destroy, inverse_of: :sales_opportunity
before_save :update_swot_score
def update_swot_score
strong = 0
weak = 0
opp = 0
threat = 0
self.swots.each do |s|
if s.strength?
strong = strong + Swot.swot_importances[s.swot_importance]
elsif s.weakness?
weak = weak + Swot.swot_importances[s.swot_importance]
elsif s.opportunity?
opp = opp + Swot.swot_importances[s.swot_importance]
elsif s.threat?
threat = threat + Swot.swot_importances[s.swot_importance]
end
end
swot_strength_score = strong - weak
swot_opp_score = opp - threat
puts swot_strength_score
puts swot_opp_score
if swot_strength_score == 0 && swot_opp_score == 0
swot_score = 0
elsif swot_strength_score > 0 && swot_opp_score >=0 || swot_strength_score = 0 && swot_opp_score > 0
swot_score = 1
elsif swot_strength_score > 0 && swot_opp_score < 0
swot_score = 2
elsif swot_strength_score <=0 && swot_opp_score < 0
swot_score = 3
elsif swot_strength_score <0 && swot_opp_score >= 0
swot_score = 4
end
puts swot_score
return swot_score
sales_opportunity.update_attributes!
end
结束
斯沃特:
class Swot < ActiveRecord::Base
belongs_to :sales_opportunity, inverse_of: :swots
validates :swot_details, presence: true
validates :sales_opportunity_id, presence: true
enum swot_type: [:strength, :weakness, :opportunity, :threat]
enum swot_importance: { minimal: 1, marginal: 2, noteworthy: 3, significant: 4, critical: 5 }
before_save :update_opportunity_score
def update_opportunity_score
sales_opportunity.update_swot_score
sales_opportunity.save
end
end
如您所见,我正在向 SalesOpportunities 添加 swot,在保存新的 Swot 时,我 运行 SalesOpportunity 模型中的 update_swot_score 方法,它遍历 swot 并计算一堆返回 swot_score 之前的值。我打算使用 swot_score 来显示每个分数的不同消息 - 但是我似乎无法在 update_swot_score 方法完成后将 swot_score 属性保存在数据库中。
我 运行 这在控制台中很好(s 被定义为我的 SalesOpportunities 之一,其中已经添加了 swot):
irb(main):014:0> s.update_swot_score
2
1
1
=> 1
这是正确的结果 - swot_strength_score 应该是 2,swot_opp_score 应该是 1,结果 swot_score 也应该是 1。但是当我然后 运行:
irb(main):015:0> s.swot_score
=> 0
如您所见,swot_score 现在为 nil(这是数据库中的默认值)。我试过使用 .save!、.save、.update_attributes,甚至尝试在方法末尾保存 sales_opportunity,但无济于事。我确定这是一个非常愚蠢的问题,但答案很明显,但我在这里做错了什么?
这是 ruby 陷阱之一。当你这样做时:
swot_score = 0
您创建了一个局部变量,您并未更改实例属性值。在你的例子中 swot_score
这样的实例属性是方法,你需要执行一个方法 swot_score=
来分配它。通过键入:
self.swot_score = 0
它会让解析器意识到你想在当前的自身对象上执行swot_score=
方法而不是创建局部变量。