7

すべてのページの上部に表示したいフォームがあるので、それを/app/views/layouts/application.html.erbファイルに含めましたが、試行するとundefined methodNilClass:Class`のエラーmodel_name'が表示されます。ページをロードします。

これがapplication.html.erbのフォームスニペットです

 <%= form_for @user do |f| %>
    <h3>Add new contact</h3>
    <%= f.text_field :first_name %><br />
    <%= f.text_field :last_name %>
    <%= f.text_field :email %>
    <hr />
    <%= f.submit "Add Contact" %>
<% end %>

これが私の/app/controllers/user_controller.rbです

class UserController < ApplicationController

    def index

    end

    def new
        @user = User.new
    end

end

フォームがapplication.html.erbファイルにあるため、どういうわけかパスを指定する必要があるため、このエラーが発生していると思いますが、これもRailsに慣れていないためです。

他に投稿が必要な場合はお知らせください。

編集 オラの提案に従って、私のapp / views / layouts/application.html.erbファイルに次のようなものがあります。

<div>
<%= yield :add_user %>
</div>

そして私のapp/views / users/new.html.erbファイルにこれがあります

<% content_for :add_user do %>
    <%= form_for @user do |f| %>
        <h3>Add new contact</h3>
        First Name<br />
        <%= f.text_field :first_name %><br />
        Last Name<br />
        <%= f.text_field :last_name %><br />
        Email<br />
        <%= f.text_field :email %>
        <hr />
        <%= f.submit "Add Contact" %>
    <% end %>
<% end %>

私のURLはレンダリングされているため、フォームはレンダリングされません。そのため、app / views / admin/index.html.erbでcontent_forを検索しhttp://localhost:3000/admin/indexています。add_user

4

5 に答える 5

13

フォームが複数のアクション(ページ)に含まれている場合は、@user何かに設定する必要があります。そうしないと、ディレクティブは失敗します(フォームform_for作成するためのフォームはありません)。

はるかに優れたアプローチ(およびRailsのデフォルト)は、アクションごとに個別のビューを用意し、それぞれにそのアクションに必要な要素のみを含め、を使用してapplication.html.erbレイアウトにロードすること<%= yield %>です。したがってapp/views/users/new.html.erb、フォームが含まれているビューが表示されます。Railsでロードパスを定義する必要があることはめったにありません。これらはすべて、モデル、コントローラー、アクションの名前、またはから派生していますroutes.rb。これは、 Railsの奥深くで実行される設定より規約核となる部分です。

編集:すべてのページに新しいオブジェクトを作成するためのフォーム必要な場合(たとえば、UserSessionsでよく使用されます)、form_for存在するオブジェクトに依存しないように書き直すことができます。

form_for(User.new)

createまたは、メソッドに投稿するように強制する必要がある場合

form_for(User.new, :url => { :action => "create" }) 

リソース駆動型の詳細についてform_forは、Ruby OnRailsAPIドキュメントを参照してください。

于 2012-06-19T03:07:57.117 に答える
13

最初にデバッグを試みましたか?Railsは初めてだとおっしゃっていますので、お願いします。そうでない場合は、ここに私のアプローチがあります。私はそれを共有したいと思います。なぜなら、(何らかの理由で)注意深くデバッグしない人がたくさんいることに驚いているからです。

(私はあなたの問題をウォークスルーできるようにテストアプリを作成しました。最初に訪問しましhttp://localhost:3000/usersた。)

まず、スタックトレースを確認します。

Users#indexのNoMethodError

/Users/david/dev/testapp/app/views/layouts/application.html.erbを表示しています。11行目が表示されています。

NilClass:Class抽出ソースの未定義メソッド `model_name'(行#11周辺):

8: </head>
9: <body>
10: 
11: <%= form_for @user do |f| %>
12:     <h3>Add new contact</h3>
13:     <%= f.text_field :first_name %><br />
14:     <%= f.text_field :last_name %>

これは、コードの11行目が問題であることを示しています。考えてください-何が問題になる可能性がありますか?ページをレンダリングしているだけなので、ルーティングはほとんどありません。構文エラーではありません。別のエラーが発生します。わかりました、それで読み続けてください:

Rails.root:/ Users / david / dev / testapp

アプリケーショントレース| フレームワークトレース| フルトレース

次に、[フレームワークトレース]をクリックすると、次のように表示されます。

activemodel(3.2.6)lib / active_model / naming.rb:163:in model_name_from_record_or_class' activemodel (3.2.6) lib/active_model/naming.rb:158:inparam_key'actionpack(3.2.6)lib / action_view / helpers / form_helper.rb:369:in `form_for'

あなたはこれらすべてを理解していないかもしれません-ほとんどの人は理解していません-しかしあなたはエラーがから来ているのを見るでしょmodel_name_from_record_or_classう。それは大きな手がかりです!param_keyform_for

open_gemソースコードを簡単に掘り下げるために、gemを使用することをお勧めします。

gem install open_gem

ここで、activemodelを見てみましょう。これは、スタックトレースの最上位のgemであるためです。

gem open activemodel

次に、正規表現検索を有効にしてこれを検索します。

def。*model_name_from_record_or_class

(なぜですか?クラスメソッドを見つけたいのですが、たとえば、で始まる定義selfもあります。)

これにより、の162行目に移動しnaming.rbます。

def self.model_name_from_record_or_class(record_or_class)
  (record_or_class.is_a?(Class) ? record_or_class : convert_to_model(record_or_class).class).model_name
end

これらすべてを理解していなくても、大きなヒントが得られます...メソッドはレコードまたはクラスからモデル名を返そうとします。なぜできないのですか?渡したパラメータ、、@userが設定されていないためです。未設定のインスタンス変数の値はnilであるため、それを使って何かをしようとするまで文句を言うことはありません。

これがこの質問と将来の質問に役立つことを願っています。

于 2012-06-19T03:33:01.767 に答える
7

この答えは実際にはSomethの答えを修正しただけですが、解決策は@user、特定のコントローラーに関連するアクションだけでなく、すべてのコントローラーアクションに設定することです。before_filterこれは、ApplicationControllerでを使用して実行できます。

class ApplicationController < ActionController::Base
  before_filter :initialize_user

  def initialize_user
    @user = User.new
  end
end

または、form_forヘルパー自体に新しいモデルを作成します(注:これは関心の分離という点では醜いですが、機能します...)

 <%= form_for User.new do |f| %>
   <h3>Add new contact</h3>
   <%= f.text_field :first_name %><br />
   <%= f.text_field :last_name %>
   <%= f.text_field :email %>
   <hr />
   <%= f.submit "Add Contact" %>
 <% end %>
于 2012-06-19T03:33:07.867 に答える
0

問題は、ページ上のすべてのアクションにフォームを追加しようとしているが、すべてのアクションでユーザーを初期化していないことです。すべてのアクションでユーザーを初期化してみてください。

class UserController < ApplicationController
    before_filter :initialize_user

    def index

    end

    def initialize_user
        @user = User.new
    end

end
于 2012-06-19T03:17:57.993 に答える
0

ユーザーコントローラー内:

def index
   @user = User.new
end
于 2014-01-11T04:43:57.543 に答える