2011-08-24 14 views
0

這是錯誤我得到:爲什麼Rails爲我的模型中存在的屬性提供了'No Method Error'? - Rails的3

NoMethodError in Devise::RegistrationsController#create 

undefined method `trial_duration' for nil:NilClass 
app/models/user.rb:120:in `set_trial_end' 

這是有關部分我User.rb

before_create :set_trial_end 

def set_trial_end 
    plan = self.plan 
    end_of_trial = Date.today + self.plan.trial_duration.days 
    self.trial_end_date = end_of_trial.to_date 
end 

什麼奇怪的是,當我看着我的數據庫,對用戶是分配計劃,並期待在trial_duration屬性,我得到的答覆:

ruby-1.9.2-p0 > tu 
=> #<User id: 29, email: "[email protected]", encrypted_password: "$2a$10$TKKQmBYem.vDq.mwDutv2u92Vick0X0jAIUQT6A9.FM....", password_salt: "$2a$10$TKKQmBYem.vDq.mwDutv2u", reset_password_token: nil, remember_token: nil, remember_created_at: nil, sign_in_count: 1, current_sign_in_at: "2011-06-18 23:03:12", last_sign_in_at: "2011-06-18 23:03:12", current_sign_in_ip: "127.0.0.1", last_sign_in_ip: "127.0.0.1", username: "test50", first_name: "Test", last_name: "Fifty", created_at: "2011-06-18 23:02:48", updated_at: "2011-06-18 23:03:12", invitation_token: nil, invitation_sent_at: nil, plan_id: 2, current_state: nil, confirmation_token: nil, confirmed_at: "2011-06-18 23:03:12", confirmation_sent_at: "2011-06-18 23:02:47", space_used: 0, failed_attempts: 0, unlock_token: nil, locked_at: nil, trial_end_date: "2011-07-02", active_subscription: nil, customer_id: nil> 
ruby-1.9.2-p0 > tu.plan 
=> #<Plan id: 2, name: "Boutique", storage: 100.0, num_of_projects: 99999, num_of_clients: 10, cached_slug: "boutique", created_at: "2011-01-31 09:46:57", updated_at: "2011-08-11 08:22:48", amount: 19, trial_duration: 14, trial_duration_unit: "days", currency: "USD", billing_cycle: 28, billing_cycle_unit: "days"> 
ruby-1.9.2-p0 > tu.plan.trial_duration 
=> 14 
ruby-1.9.2-p0 > tu.plan.trial_duration.days 
=> 14 days 

所以不知道爲什麼Rails的是給我的錯誤。

任何想法?

編輯1:

在我看來,我有這樣的:

<% if params[:promo] %> 
    <%= text_field_tag "xcode", nil, :placeholder => "Coupon Code" %><br /> 
<%= hidden_field_tag(:plan_id, "1") %> 
<% end %> 

與後,從我的日誌,你可以看到參數plan_id設置爲1

Started POST "/users" for 127.0.0.1 at 2011-08-24 03:11:07 -0500 
    Processing by Devise::RegistrationsController#create as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"Jp2GHxnuVOVnI/sfr1CB4EQ9URCTJynv/2Ek4AiU8Lg=", "user"=>{"username"=>"test.user", "first_name"=>"Testing", "last_name"=>"User", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "email"=>"[email protected]"}, "xcode"=>"testcouponcode", "plan_id"=>"1", "commit"=>"Register"} 
nil 

但我仍然收到下一頁上的錯誤Plan can't be blank

我已經添加了after_validation而不是after_create,所以我不再是NoMethodError。但問題沒有解決。

回答

5

您使用的是before_create掛鉤這是假設該self.plan設置:

before_create :set_trial_end 

def set_trial_end 
    #... 
    end_of_trial = Date.today + self.plan.trial_duration.days 

而你的錯誤說:

undefined method `trial_duration' for nil:NilClass 

所以self.plan是你set_trial_end通話期間nil

也許你想要一個after_create掛鉤,這樣你就可以使用一些實例數據。即使如此,你會想檢查self.plan.nil?(以防萬一),並使用驗證,以確保你得到一個:

class User < ActiveRecord::Base 
    validates_presence_of :plan_id 
    #... 

或者,也許一個after_validation鉤將更好地爲您服務。

+0

我將如何使用'self.plan.nil?'?因爲如果我在驗證中添加 - 這是完全有道理的 - 並沒有注意確保已選擇該計劃。我試圖找出如果'self.plan.nil?'返回true,我會做什麼......在該方法中。我什麼都不做? – marcamillion

+0

@marcamillion:問題在於[order in steps in](http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html),'before_create'和'after_create'掛鉤在驗證之前被調用。你可能要等到'after_validation'。在嘗試使用'self.plan'之前,你會檢查'如果self.plan.nil?'。 –

+0

此外,在這種特殊情況下,發生的事情是,用戶將訪問一個特定頁面「register?plan_id = 1&promo = awesomecoupon」,並將plan_id硬連接到URL中。當發生這種情況時,我從視圖中刪除了'f.collection_select',以允許他們選擇計劃 - 想法是plan_id位於URL中的參數中。但是,一旦我改爲'after_create',它不會保存它,因爲它說計劃不能留空。所以我想我的問題是,如何根據模型中特定方法的URL中的參數設置plan_id? – marcamillion

相關問題