0

我有一个看起来很简单的代码,让我在这个地方摸不着头脑。

这是一个用户模型:

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 控制器中,我有:

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 值。其次,为什么他们用 nil 值保存(即通过验证)。

任何帮助都将受到欢迎。不过,我感觉到一个掌心来了!:)

4

2 回答 2

1

事实证明,Rails 会阻止您在没有“强参数”的情况下成功使用内置的“保存”和“创建”方法。

解决方法不是从控制器中保存,而是在模型本身中使用如下自定义功能进行保存:

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 接受的合法参数。跳这对某人有用。

于 2015-03-30T23:47:00.110 回答
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!)

结尾

我希望这可以解决您的问题。

于 2015-01-25T20:17:24.547 回答