Подтвердить что ты не робот

Почему мои рельсы откатываются при попытке пользователя.

Я установил пример приложения RailsTutorial (приложение, подобное твитеру), и я пытаюсь понять, почему следующий фрагмент кода консоли не обновляет базу данных при попытке обновить db пользователя. Я ожидаю, что информация пользователя будет обновляться после использования user.save. Однако это возвращается к неотредактированным данным. Это связано с ограничением пользователя?

Контроллер пользователей:

class UsersController < ApplicationController

#before_filter :signed_in_user, only: [:index, :edit, :update, :destroy, :following, :followers]
# By default before filters apply to all actions
#before_filter :correct_user, only: [:edit, :update]
  def edit
    @user = User.find(params[:id])
  end

  def update

    @user = User.find params[:id]

    respond_to do |format|

    if @user.update_attributes(params[:user])
      flash[:notice] = "Profile updated"
      format.html { redirect_to(@user, :notice => 'User was successfully updated.') }
      format.json { respond_with_bip(@user) }
    else

      format.html { render :action => "edit" }
      format.json { respond_with_bip(@user) }
    end
    end
 end

  private


  def correct_user
    @user = User.find(params[:id])
    redirect_to(root_path) unless current_user?(@user)
  end

  def admin_user
    redirect_to(root_path) unless current_user.admin?
  end


end

Консоль Rails:

1.9.3-p392 :001 > user = User.find(109)


User Load (8.2ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", 109]]
 => #<User id: 109, name: "laurie", email: "[email protected]", created_at: "2013-09-26 18:10:12", updated_at: "2013-09-26 18:10:12", password_digest: "$2a$10$aXEtun8Z2Deqy2wNxvFRNOjPczKQkYc1vDezP5OduJuF...", remember_token: "YhIUhgFm9iMewxdNOHJ45A", admin: false> 

1.9.3-p392 :002 > user.name = "larry"
 => "larry" 

1.9.3-p392 :003 > user.save
   (0.2ms)  begin transaction
  User Exists (0.6ms)  SELECT 1 AS one FROM "users" WHERE (LOWER("users"."email") = LOWER('[email protected]') AND "users"."id" != 109) LIMIT 1
   (0.1ms)  rollback transaction
 => false 

Модель пользователя:

class User < ActiveRecord::Base

# Declaration of public variables   
  attr_accessible :email, :name, :password, :password_confirmation
  has_secure_password
  has_many :microposts, dependent: :destroy
  has_many :relationships, foreign_key: "follower_id", dependent: :destroy
  has_many :followed_users, through: :relationships, source: :followed
  has_many :reverse_relationships, foreign_key: "followed_id", class_name: "Relationship", dependent: :destroy
  has_many :followers, through: :reverse_relationships, source: :follower

  before_save {email.downcase!}
  before_save :create_remember_token

  validates :name, presence: true, length: {maximum: 50}
  VALID_EMAIL_REGEX = /\A[\w+\-.][email protected][a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, format: {with: VALID_EMAIL_REGEX}, uniqueness: {case_sensitive: false}
  validates :password, presence: true, length: {minimum: 6}
  validates :password_confirmation, presence: true
  after_validation {self.errors.messages.delete(:password_digest)}

 private
    def create_remember_token
        self.remember_token = SecureRandom.urlsafe_base64
    end
end
4b9b3361

Ответ 1

Возможно, у вашей модели пользователя есть проверки, которые не выполняются. Поскольку вы не разместили эти сообщения, я не могу решить ваш вопрос. Чтобы сделать жизнь проще, вы можете отлаживать, почему ваш пользователь не желает сохранять.

Попробуйте запустить

user.errors.full_messages

который должен дать вам подсказку, что происходит не так.

Ответ 2

Я знаю, что это старый пост, но, надеюсь, это может помочь кому-то пройти этот учебник в будущем.

Как говорится в принятом ответе, это связано с проверками, которые не выполняются. Я столкнулся с этой проблемой и обнаружил, что еще одним обходным решением является использование метода update_attribute для объекта user. Например, если вы хотите обновить поле name объекта user и автоматически сохранить его в базе данных, не касаясь виртуальных полей password и password_confirmation, используйте следующее:

user.update_attribute(:name, "larry")

Это обновит только поле name и сохранит его в базе данных (не нужно вызывать метод save), не касаясь полей password и password_confirmation.

Ответ 3

После того, как вы попытаетесь сохранить или проверить экземпляр активной записи, вы можете просмотреть дополнительную информацию о том, что произошло с несколькими полезными командами.

user = User.find(108)
user.name = "Larry"
user.valid? # returns false
user.errors.messages # returns something like {email: "Cant be blank"}

Очевидно, что я сделал эту ошибку, потому что не знаю, как выглядит ваш файл модели, но если он возвращает ее по одной из двух причин. Во-первых, ваши проверки не удались. Если они не являются сообщениями об ошибках, вероятно, потому что что-то в вашей цепочке фильтров возвращает false. Например

class User << ActiveRecord::Base
  before_save :accidentally_return_false

  def accidentally_return_false
    self.some_boolean = (condition == value)
  end
end

user = User.new( params )
user.save # where condition does not equal value
user.valid? # false because of the before save method

Надеюсь, что поможет

Ответ 4

При сохранении откатов используйте save! вместо этого, и журнал ошибок будет напечатан.

Ответ 5

Ваши проверки не проходят. Вы можете сделать:

user.errors.full_messages

в консоли после неудачного сохранения, чтобы узнать, почему.

Ответ 6

У меня была такая же проблема, и никаких ошибок не было. Оказалось, что моя функция before_save возвращала false, в результате чего сохранение было отменено (я предполагаю, что я новичок в рельсах).

Я пытался установить значение логического значения, которое можно было установить только после того, как файл был загружен.

Вот что я делал:

before_save :set_orientation

def set_orientation
  # ...do stuff...
  self[:is_landscape] = ratio > 1  # stores AND returns the boolean value!!
end

Последняя строка в функции была также неявным возвратом, который я не хотел делать. Мое решение состояло в том, чтобы явно сделать возврат:

before_save :set_orientation

def set_orientation
  # ...do stuff...
  self[:is_landscape] = ratio > 1  # store the boolean value
  return                           # now return
end

Ответ 7

У меня была та же проблема с базой данных, которая возвращала мои транзакции в консоли, когда я пытался обновить свойство admin у пользователя. Если вы занимаетесь учебным пособием по Hartl rails, проблема в том, что если вы наберете user.errors.messages в консоли, он скажет вам, что пароль слишком короткий. Это потому, что в модели есть проверка пароля, прежде чем она сохранит и хеширует ваш пароль в password_digest.

Работа с этим в консоли выполняет вашу обычную деятельность, например, настройку user.admin = true, а затем, когда вы закончите, введите user.password = "foobar", затем введите user.password_confirmation = "foobar", а затем, когда вы выполните user.save, он зафиксирует все ваши изменения.

Ответ 8

Попробуйте обновить базу данных:

rails db:migrate

Ответ 9

На случай, если это когда-нибудь кому-нибудь пригодится в будущем - у меня была похожая проблема, и причиной откатов было то, что мои данные в том виде, в каком они были, не прошли проверку (проверки были выполнены после обнаружения проблемы). Исправление данных вручную решило проблему.