在我的应用程序中,我有一个与 status_updates 模型有很多关系的用户模型。
目前,我的数据库只保存了 1 个用户和零个 status_updates。
奇怪的是,当我在 consol 中搜索 status_updates 或这些对象之间的关系时,确认数据库中的 status_updates 为 nil。
StatusUpdate.count
(0.2ms) SELECT COUNT(*) FROM "status_updates"
=> 0
StatusUpdate.any?
(0.1ms) SELECT COUNT(*) FROM "status_updates"
=> false
user.status_updates.count
(0.2ms) SELECT COUNT(*) FROM "status_updates" WHERE "status_updates"."user_id" = 1
=> 0
user.status_updates.any?
(0.2ms) SELECT COUNT(*) FROM "status_updates" WHERE "status_updates"."user_id" = 1
=> false
所以,这对我来说很清楚。
但是,当我在我的应用程序中编写以下内容时,会返回一个 status_update 对象!
def end_date
if self.status_updates.any? == false
return self.status_updates.any?
elsif self.status_updates.any? == true
return self.status_updates.first
end
end
这是我认为的电话
current_user.end_date
这就是返回给视图的内容:
#<StatusUpdate:0x007fa99765d6f8>
如果我将视图中的调用更改为:
current_user.status_updates.first
=> <StatusUpdate:0x007fa99740b5f8>
但是,如果我这样称呼:
current_user.status_updates.count
=> 0
current_user.status_updates.any?
=> true
在我只使用 current_user.status_updates 的视图中,它返回
[#<StatusUpdate id: nil, created_at: nil, updated_at: nil, user_id: 1, current_weight: 0.0, current_bf_pct: 0.0, current_lbm: 0.0, current_fat_weight: 0.0, change_in_weight: nil, change_in_bf_pct: nil, change_in_lbm: nil, change_in_fat_weight: nil, total_weight_change: nil, total_bf_pct_change: nil, total_lbm_change: nil, total_fat_change: nil>]
这里发生了什么?!
用户模型关系
has_many :status_updates, 依赖: :destroy
状态更新模型关系
属于_to:用户
状态更新模型
class StatusUpdate < ActiveRecord::Base
belongs_to :user
after_initialize :default_values
before_save :sanitize
attr_accessible :current_weight,
:current_bf_pct,
:current_lbm,
:current_fat_weight,
:change_in_weight,
:change_in_bf_pct,
:change_in_lbm,
:change_in_fat_weight,
:total_weight_change,
:total_bf_pct_change,
:total_lbm_change,
:total_fat_change,
:created_at
validates :user_id, presence: true
validates :current_bf_pct, presence: true, numericality: true, length: { minimum: 2, maximum:5 }
validates :current_weight, presence: true, numericality: true, length: { minimum: 2, maximum:5 }
validates :current_lbm, presence: true
validates :current_fat_weight, presence: true
def sanitize
if self.current_bf_pct >= 0.5
self.current_bf_pct /= 100
if self.current_bf_pct <= 0.04
self.current_fb_pct *= 100
end
end
self.current_fat_weight = self.current_weight * self.current_bf_pct
self.current_lbm = self.current_weight - self.current_fat_weight
end
def default_values
if self.created_at == nil
self.current_bf_pct = 0.20
self.current_weight = 0
self.current_lbm = 0
self.current_fat_weight = 0
self.change_in_weight = 0
self.change_in_bf_pct = 0
self.change_in_lbm = 0
self.change_in_fat_weight = 0
self.total_weight_change = 0
self.total_bf_pct_change = 0
self.total_lbm_change = 0
self.total_fat_change = 0
end
end
def previous_status_update
previous_status_update = user.status_updates.where( "created_at < ? ", self.created_at ).first
if previous_status_update == nil
return self
else
previous_status_update
end
end
default_scope order: 'status_updates.created_at DESC'
end
用户模型:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
before_create :sanitize
has_many :status_updates, dependent: :destroy
has_many :meals, dependent: :destroy
has_many :custom_foods, dependent: :destroy
has_many :meal_foods, through: :meals
# after_initialize :default_values
attr_accessor :user_password, :user_password_confirmation, :current_password
attr_accessible :email,
:password,
:password_confirmation,
:current_password,
:goal,
:measurement,
:bmr_formula,
:fat_factor,
:protein_factor,
:remember_me,
:deficit_amnt,
:target_bf_pct,
:activity_factor,
:current_password
validates :email, presence: true
validates :target_bf_pct, presence: true, on: :update, length: { minimum: 3, maximum: 4 }
validates :activity_factor, presence: true, on: :update
validates :deficit_amnt, presence: true, on: :update
validates :fat_factor, presence: true, on: :update
validates :protein_factor, presence: true, on: :update
def new?
self.created_at <= 1.minutes.ago.to_date ? true : false
end
def sanitize
#inputs
self.activity_factor = 1.3
self.deficit_amnt = 1
self.target_bf_pct = 10
self.fat_factor = 0.45
self.protein_factor = 1
end
def end_date
if self.status_updates.any? == false
#Time.now
self.status_updates.any?
elsif self.status_updates.any? == true
#(self.start_date + self.weeks_to_goal.to_i.weeks).strftime("%m/%d/%Y")
self.status_updates
end
end
def start_date
if self.status_updates.any? == true
self.status_updates.first.created_at
end
end
def daily_caloric_deficit
self.tdee.to_d - self.daily_intake.to_d
end
def current_fat_weight
BigDecimal(self.latest_status_update.current_fat_weight, 4)
end
def current_lbm
BigDecimal(self.latest_status_update.current_lbm, 4)
end
def current_bf_pct
BigDecimal(self.latest_status_update.current_bf_pct * 100, 4)
end
def current_weight
BigDecimal(self.latest_status_update.current_weight, 4)
end
def total_weight
self.latest_status_update.current_weight
end
# def lbm
# self.latest_status_updates.current_lbm
# end
def recent_weight_change
BigDecimal(self.latest_status_update.current_weight - self.latest_status_update.previous_status_update.current_weight, 2)
end
def recent_lbm_change
BigDecimal(self.latest_status_update.current_lbm - self.latest_status_update.previous_status_update.current_lbm, 2)
end
def recent_fat_change
BigDecimal(self.latest_status_update.current_fat_weight - self.latest_status_update.previous_status_update.current_fat_weight, 3)
end
def total_lbm_change
BigDecimal(self.latest_status_update.current_lbm - self.oldest_status_update.current_lbm, 3)
end
def total_fat_change
BigDecimal(self.latest_status_update.current_fat_weight - self.oldest_status_update.current_fat_weight, 3)
end
def total_weight_change
BigDecimal(self.latest_status_update.current_weight - self.oldest_status_update.current_weight, 3)
end
def last_date
self.status_updates.last.created_at.strftime("%m/%d/%Y")
end
def beginning_date
self.status_updates.first.created_at.strftime("%m/%d/%Y")
end
def latest_status_update
self.status_updates.first
end
def oldest_status_update
self.status_updates.last
end
def bmr
cur_lbm = self.current_lbm
cur_lbm *= 0.45
'%.2f' % (370 + (21.6 * cur_lbm.to_d))
end
def target_weight
tar_bf_pct = self.target_bf_pct /= 100
'%.2f' % ((self.total_weight * tar_bf_pct)+ self.current_lbm)
end
def fat_to_burn
'%.2f' % (self.total_weight.to_d - self.target_weight.to_d)
end
def tdee
'%.2f' % (self.bmr.to_d * self.activity_factor.to_d)
end
def deficit_pct
daily_cal_def = ((self.deficit_amnt.to_f * 3500)/7)
(daily_cal_def.to_d/self.tdee.to_d)
end
def daily_calorie_burn
'%.2f' % (self.tdee.to_d * self.deficit_pct.to_d)
end
def weekly_calorie_burn_rate
'%.2f' % (self.daily_calorie_burn.to_d*7)
end
def weeks_to_goal
'%.2f' % (self.fat_to_burn.to_d*3500/self.weekly_calorie_burn_rate.to_d)
end
def daily_intake
'%.2f' % (self.tdee.to_d - self.daily_calorie_burn.to_d)
end
def total_grams_of(macro)
self.meal_foods.map(¯o).inject(:+)
end
def pct_fat_satisfied
#how much of a macro is needed?
fat_needed = self.fat_factor * self.current_lbm
#how much is in the meal?
fat_provided = self.total_grams_of(:fat)
#percent needed
pct_fulfilled = fat_provided.to_f/fat_needed.to_f
BigDecimal(pct_fulfilled, 2)*100
end
def pct_protein_satisfied
#how much protien is needed?
protein_needed = self.protein_factor * self.current_lbm
#how much protien is provided?
protein_provided = total_grams_of(:protien)
#pct of protien satisfied?
pct_fulfilled = protein_provided.to_f/protein_needed.to_f
BigDecimal(pct_fulfilled, 2)*100
end
def pct_carbs_satisfied
#how many carbs are needed?
cals_required = self.tdee.to_f - (self.tdee.to_f * self.deficit_pct.to_f)
fat_cals = total_grams_of(:fat) * 9
protien_cals = total_grams_of(:protien) * 4
#how many carbs are provided?
cals_provided = fat_cals + protien_cals
cals_balance = cals_required - cals_provided
carbs_needed = cals_balance/4
carbs_provided = total_grams_of(:carbs)
BigDecimal(carbs_provided / carbs_needed, 2) * 100
end
end
我试过重置我的数据库,同样的问题出现了。
回顾一下:
似乎正在初始化 status_update,并且该对象的初始化版本是视图可用的。所有属性都是初始化的,这就是为什么它没有 id 或创建时间的时间戳......因为它从未被创建。
但是,当我尝试从控制台访问它时,我意识到它给了我“零”和所有可预测的值,因为在控制台中它正在寻找关系中已经创建的对象关系。
所以这里更精确的问题是视图返回对象的初始化版本而不是控制台返回什么?
当应用程序在用户模型中遇到一个方法时,它会抛出一个错误,因为当它调用类似的东西时 status_update 不存在
self.status_updates.first