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 у меня есть:

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 равны нулю.

Во-первых, я до сих пор не понимаю, почему эти два поля имеют нулевые значения. И, во-вторых, почему они сохраняются (т.е. проходят проверку) с нулевыми значениями.

Любая помощь будет более чем приветствуется. Тем не менее, я чувствую приближающуюся ладонь! :)


person igreka    schedule 10.01.2015    source источник
comment
a = ApiAccount.new(:access_token =› response[:access_token]), затем отладьте его (отметьте a.errors, чтобы увидеть результат проверки). учетная запись @user.api_account ‹‹ a и отладка @user.errors   -  person Razor    schedule 10.01.2015
comment
Нет никакого сообщения об ошибке вообще. Я проверяю их в консоли; ничего не всплывает. Может быть, я назначаю атрибуты учетной записи api_account вручную, а не с сильными параметрами?   -  person igreka    schedule 13.01.2015


Ответы (2)


Оказывается, 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. Хоп это кому-то пригодится.

person igreka    schedule 30.03.2015

@igreka, я думаю, вам следует попробовать это в своем контроллере api_account, например -

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

частный

определение api_account_params

json_params=ActionController::Parameters.new(JSON.parse(ответ[:access_token]))

вернуть json_params.require(:api_account).разрешить!)

конец

Я надеюсь, что это может решить вашу проблему.

person Chitra    schedule 25.01.2015