54

RailsTutorial サンプル アプリ (Twitter のようなアプリケーション) をインストールしました。ユーザー データベースを更新しようとすると、次のコンソール コードがデータベースを更新しない理由を理解しようとしています。を使用すると、ユーザー情報が更新されることを期待しています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: "auriepage@gmail.com", 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('auriepage@gmail.com') 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+\-.]+@[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
4

8 に答える 8

20

これは古い投稿であることは承知していますが、今後このチュートリアルを進める人に役立つことを願っています。

受け入れられた回答が示すように、これは検証が満たされていないためです。私もこの問題に遭遇し、別の回避策はオブジェクトでupdate_attributeメソッドを使用することであることがわかりました。userたとえばname、オブジェクトのフィールドを更新し、userそれを自動的にデータベースに保存する場合、仮想passwordおよびpassword_confirmationフィールドに触れる必要はありません。次のように使用します。

user.update_attribute(:name, "larry")

nameこれにより、フィールドのみが更新され、データベースに保存されます (メソッドを呼び出す必要はありません)。フィールドとフィールドsaveに触れる必要はありません。passwordpassword_confirmation

于 2015-06-19T21:47:02.390 に答える
2

これと同じ問題があり、エラーは保存されていませんでした。私の関数が false を返していることが判明したbefore_saveため、保存がキャンセルされました(私はレールに慣れていないのでしょうか)。

ファイルがアップロードされた後にのみ設定できるブール値の値を設定しようとしていました。

これが私がやっていたことです:

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
于 2014-05-30T05:00:05.670 に答える