0

別のヘアプラー。これで2日間戦った後、ここで何が悪いのかわかりません。

基本的に、モデルによってトリガーされるフォーム検証があります。

validates :user, :presence => true, :uniqueness => true
validates :email, :presence => true, :uniqueness => true, :on => :create
validates :passwordHash, :presence => true, :confirmation => true, :on => :create

空ではないユーザーは、更新フォーム ビューで動作します。

= simple_form_for @user do |f|      
  = f.input :user
  = f.input :locale
  = f.input :localeLanguage, :label => 'Language', :as => :select, :collection => $language_array 
  = f.input :moderator
  = f.input :email
  = f.input :passwordHash, :label => 'Password'

ただし、新しいユーザーのビューではありません:

  = simple_form_for @user do |f|  
    %table.table-condensed
      %tr
        %td
          =f.input :user, :label => false, :placeholder => 'username'
      %tr
        %td
          = f.input :passwordHash, :label => false, :placeholder => 'password'
      %tr
        %td
          = f.input :email, :label => false, :placeholder => 'email'
      %tr
        %td
          = f.submit "Create User", :class => 'btn btn-primary'

これらのビューの唯一の違いは、ユーザーがすでにログインしているため、最初のビューにはセッションが作成されているのに対し、2 番目のビューには作成されていないことです。しかし、私の知る限り、これは違いを生むべきではありません。もちろん、updateフォームには実際の @user オブジェクトがありますが、newそれは空です。しかし、Ryan Bates の新しいユーザー検証の railscast を見たことがありますが、彼はほとんど同じことをしています。

空の値でフォームを送信した後にusers#createアクションが呼び出されます (これは可能ではありません)。passwordHashが空であるため、もちろんエラーが発生します。

パスワードの確認を支援するために追加のgemを使用していないことを指摘する必要があります(railscastでは、Batesが使用しbcryptますが、パスワードハッシュを別の方法で作成するため、使用できません。さらに、それはパスワード確認の魔法のためだと思いますそれだけ)。いずれにせよ、これはフォームの検証に影響を与えるべきではありませんか?

ここではどんな理論やアイデアでも大歓迎です。私は手でそれを行うためにいくつかのくだらないJavaScriptを書き込もうとしていますが、それはひどいものであり、おそらく1週間かかるでしょう.

ありがとう。

編集

Rachid のリクエストによるnewと、createアクションは次のとおりです。

  def new
    @user = User.new
  end

  def create
    #failsafe for failing form validation
    unless params[:passwordHash].present?
      redirect_to new_user_path, :notice => 'User or password cannot be blank' 
    else
      password_and_salt = User.hash_password(params[:passwordHash])
      hashed_password = password_and_salt[:password]
      user_salt = password_and_salt[:salt]
      @user = User.new(:user => params[:user], :passwordHash => hashed_password, :salt => user_salt)
      if @user.save
        session[:user_id] = @user.id
        redirect_to session[:item_to_edit]
      else
        redirect_to new_user_path, :notice => "User already exists, please pick another one"
      end
    end
  end

編集 2

create最初の回答に基づいてメソッドを書き直しましたが、それでもエラーが発生します:

def create
    respond_to do |format|
      if params[:passwordHash].present? && params[:user].present? 
        password_and_salt = User.hash_password(params[:passwordHash])
        hashed_password = password_and_salt[:password]
        user_salt = password_and_salt[:salt]
        @user = User.new(:user => params[:user], :passwordHash => hashed_password, :salt => user_salt, :online_user => 1 )
        if @user.save
          session[:user_id] = @user.id
          redirect_to session[:item_to_edit]
        else
          format.html { render :action => "new" }
          format.json { render :json => @user.errors, :status => :unprocessable_entity }
        end
      else
          format.html { render :action => "new" }
          format.json { render :json => @user.errors, :status => :unprocessable_entity }
      end
    end
  end

エラーはundefined method 'model_name' for NilClass:Class次の行です。

= simple_form_for @user do |f|

明らかに@user = User.new、フォームに戻っていません。この時点で、createメソッドが正しく動作し、エラー メッセージを表示するためのメソッドをどのように記述すればよいかについて、少し混乱しています。しかし、私は私が近づいていると感じます:)

@misha、updateこれがコントローラーアクションです。これは非常に標準的な足場です。

def update
    @user = User.find(params[:id])

    respond_to do |format|
      if @user.update_attributes(params[:user])
        if session[:return_to]
          format.html { redirect_to session[:return_to], :notice => 'User was successfully updated.' }
        else
          format.html { redirect_to users_path, :notice => 'User was successfully updated.' }
        end

        format.json { head :ok }
      else
        format.html { render :action => "edit" }
        format.json { render :json => @user.errors, :status => :unprocessable_entity }
      end
    end
  end
4

1 に答える 1

0

まず第一に、あなたがここで想定していることは間違っています:

空の値でフォームを送信した後にusers#createアクションが呼び出されます (これは可能ではありません)。もちろん、passwordHash が空であるため、エラーが発生します。

users#createが呼び出され、実際に発生する可能性があります。これを処理するのは作成アクションです。あなたの問題は、@user保存されていない場合にリダイレクトを行うという事実だと思います。エラー メッセージを表示できるように、ビューを再度レンダリングする必要があります。

したがって、代わりに:

redirect_to new_user_path, :notice => "User already exists, please pick another one"

試す:

render :action => 'new'

コメントに基づいて編集します。

検証が失敗すると、Rails は@user.errors自動的に入力します。コントローラーで何もする必要はありません (つまり、作成アクション)。ビューにエラーを表示@user.errorsするだけです。

現在発生しているエラーについて:

エラーが発生する理由は、@user設定されていないためです。createメソッドを次のように書き直す必要があります。

def create
  respond_to do |format|
    if params[:user][:passwordHash].present?
      password_and_salt = User.hash_password(params[:user][:passwordHash])
      hashed_password = password_and_salt[:password]
      user_salt = password_and_salt[:salt]
    end

    @user = User.new(params[:user].merge({:passwordHash => hashed_password, :salt => user_salt, :online_user => 1}))

    if @user.save
      session[:user_id] = @user.id
      redirect_to session[:item_to_edit]
    else
      format.html { render :action => "new" }
      format.json { render :json => @user.errors, :status => :unprocessable_entity }
    end
  end
end
于 2012-05-03T12:13:15.067 に答える