2015-01-10 61 views
0

我有一個簡單的代碼讓我敲着腦袋。Rails 4:模型驗證不起作用創建

下面是一個用戶模型:

class User < ActiveRecord::Base 
    has_one :api_account, inverse_of: :user, dependent: :destroy 

# Other user-specific validations come after 

下面是相關聯api_account:

class ApiAccount < ACtiveRecord::Base 
    belongs_to :user, inverse_of: :api_account 
    validates :access_token, presence: true 
    validates :user, presence: true, 
        uniqueness: true 

在api_account控制器,I具有:

response = ### Some JSON response from a distant server 

@api_account = @user.create_api_account(:access_token => response[:access_token]) 

用於api_account架構看起來像這樣:

create_table "api_accounts", force: true do |t| 
    t.text  "access_token" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    t.integer "user_id" 
end 

add_index "api_account", ["user_id"], name: "index_api_accounts_on_user_id" 

每當我運行代碼時,我都會在響應變量中獲得訪問令牌。當我使用rails控制檯來檢查數據庫時,我看到一個保存的實例具有有效的創建和更新時間,但access_token和user_id沒有值。

首先,我還是不明白爲什麼這兩個字段有nil值。其次,爲什麼他們保存(即通過驗證)與零值。

任何幫助將更受歡迎。雖然,我感覺到一個臉掌! :)

+1

a = ApiAccount.new(:access_token => response [:access_token])然後調試它(檢查'a.errors'查看驗證結果)。 @ user.api_account << a和debug @ user.errors – Razor

+0

根本沒有任何錯誤消息。我在控制檯中檢查他們;沒有東西彈出。難道是我手動分配屬性到「api_account」而不是強大的參數? – igreka

回答

1

事實證明,Rails阻止您在沒有「強參數」的情況下成功使用內置的「save」和「create」方法。

解決方法是不是從控制器保存,但模型本身具有自定義函數這樣的範圍內:

def CloudAccount.create_or_update(user, provider, token) 
raw_params = {provider: provider, access_token: access_token} 
params  = ActionController::Parameters.new(raw_params) 
if @cloud_account = CloudAccount.find_by(user_id, provider: provider) 
    @cloud_account.update(params.permit(:access_token) 
else 
    @cloud_account = user.cloud_accounts.create(params.permit(:provider, :access token 
end 

正如你所看到的,它的API訪問代碼隔離到專門的只是更容易模型和與用戶模型相關的控制器。

這個技巧似乎是ActionController::Parameters.new,它創建了Rails接受的合法參數。跳這對某人有用。

0

@igreka,我想你應該在你的api_account控制器喜歡嘗試這個 -

@api_account = @ user.create_api_account(:=的access_token> api_account_params)

私人

def api_account_params

json_params = ActionController :: Parameters.new(JSON.parse(response [:access_token]))

回報json_params.require(:api_account)!.permit)

我希望這可以解決您的問題。