私のアプリケーションには、status_updates モデルとの has many 関係を持つユーザー モデルがあります。
現在、私のデータベースには 1 人のユーザーしか保存されておらず、status_updates は保存されていません。
奇妙なのは、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
ステータス更新モデルの関係
所属先:ユーザー
ステータス更新モデル
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、または作成時のタイムスタンプがありません...作成されていないためです。
ただし、コンソールからアクセスしようとすると、「nil」とすべての予測可能な値が返されることに気付きました。これは、コンソールで既に作成されたオブジェクトの関係を探しているためです。
ここでのより正確な質問は、コンソールが返すものではなく、オブジェクトの初期化されたバージョンを返すビューですか?
アプリがユーザーモデル内のメソッドにヒットすると、次のような呼び出し時に status_update が存在しないため、エラーがスローされます
self.status_updates.first