Rails 4:模型验证不适用于创建

时间:2015-01-10 18:17:18

标签: ruby-on-rails ruby ruby-on-rails-4.2

我有一些简单的代码,让我在这个地方摇头。

以下是用户模型:

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。

首先,我仍然不明白为什么这两个字段的值为零。第二,为什么他们用零值保存(即通过验证)。

任何帮助都会受到欢迎。虽然,我感觉脸上的手掌来了! :)

2 个答案:

答案 0 :(得分: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接受的合法参数。跳这对某人有用。

答案 1 :(得分:0)

@igreka,我想你应该在你的api_account控制器中尝试这个 - 比如

@api_account = @ user.create_api_account(:access_token =&gt; api_account_params)

私有

def api_account_params

json_params = ActionController的:: Parameters.new(JSON.parse(的响应[:的access_token] ))

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

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