1

ユーザー (x) が別のユーザー (y) を友達として追加できるようにしたいのですが、ユーザー (x) はユーザー (y) のプロフィール ページにいます。has_many_through を設定すると、User Index View からのみ友達を追加できることを除いて、すべてが機能します。よろしくお願いします...コードは以下のとおりです。

また:

view/profile/show.html.erb に「友達」リンクを配置したかったのです。@users = User.all を既存の profiles_controller.rb に追加すると、エラーが発生しました - undefined method friendships' for nil:NilClass. When I replaced @user = User.find(params[:id]) with @users = User.all I received the error - NoMethodError in Profiles#show... undefined methodinverse_friends' for nil:NilClass

UserIndexView では動作するが ProfileShowView では動作しないコード:

% for user in @users %>
    <div class="user">
    <p>
      <strong><%=h user.email %> <%= user.id %></strong>
      <%= link_to "Add Friend", friendships_path(:friend_id => user), :method => :post%>
    <div class="clear"></div>
    </p>
    </div>
<% end %>

次のエラーが発生します。

    NoMethodError in Profiles#show
    Showing /Users/mgoff1/LOAP_1.2.2/app/views/profiles/show.html.erb where line #13 raised:
undefined method `each' for nil:NilClass
Extracted source (around line #13):
10: 
11: 
12: 
13:   <% for user in @users %>
14:       <div class="user">
15:         <p>
16:           <strong><%=h user.email %> <%= user.id %></strong>
    . . .

app/views/profiles/show.html.erb:    13:in`_app_views_profiles_show_html_erb___2905846706508390660_2152968520'
app/controllers/profiles_controller.rb:19:in `show'

残りのコードは以下のとおりです。

友情.rb

class Friendship < ActiveRecord::Base
attr_accessible :create, :destroy, :friend_id, :user_id

 belongs_to :user
 belongs_to :friend, :class_name => "User"
end

user.rb

    class User < ActiveRecord::Base
  has_many :friendships
  has_many :friends, :through => :friendships
  has_many :inverse_friendships, :class_name => "Friendship", :foreign_key =>   "friend_id"
  has_many :inverse_friends, :through => :inverse_friendships, :source => :user

  # Include default devise modules. Others available are:
  # :token_authenticatable, :confirmable,
  # :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :password, :password_confirmation, :remember_me,    :profile_attributes
  # attr_accessible :title, :body



  has_one :profile
  accepts_nested_attributes_for :profile

  before_save do | user |
  user.profile = Profile.new unless user.profile
 end
end

friends_controller.rb

class FriendshipsController < ApplicationController
  def create
    @friendship = current_user.friendships.build(:friend_id => params[:friend_id])
    if @friendship.save
      flash[:notice] = "Added friend."
      redirect_to current_user.profile
    else
      flash[:error] = "Unable to add friend."
      redirect_to root_url
    end
   end

  def destroy
    @friendship = current_user.friendships.find(params[:id])
    @friendship.destroy
    flash[:notice] = "Removed friendship."
    redirect_to current_user.profile
  end
 end

users_controller.rb

class UsersController < ApplicationController
  def show
    @user = User.find(params[:id])
  end

  def index
    @users = User.all
  end
end

profile_controller.rb

class ProfilesController < ApplicationController
  # GET /profiles
  # GET /profiles.json
  def index
    @profiles = Profile.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @profiles }
    end
  end

  # GET /profiles/1
  # GET /profiles/1.json
  def show
    @user = User.find(params[:id])
    @profile = Profile.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @profile }
    end
  end

  # GET /profiles/new
  # GET /profiles/new.json
  def new
    @profile = Profile.new

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @profile }
    end
  end

  # GET /profiles/1/edit
  def edit
    @user = User.find(params[:id])
    @profile = Profile.find(params[:id])
  end

  # POST /profiles
  # POST /profiles.json
  def create
    @profile = Profile.new(params[:profile])

    respond_to do |format|
      if @profile.save
         format.html { redirect_to @profile, notice: 'Profile was successfully created.' }
         format.json { render json: @profile, status: :created, location: @profile }
      else
        format.html { render action: "new" }
         format.json { render json: @profile.errors, status: :unprocessable_entity }
      end
    end
  end

  # PUT /profiles/1
  # PUT /profiles/1.json
  def update
    @profile = Profile.find(params[:id])

    respond_to do |format|
      if @profile.update_attributes(params[:profile])
        format.html { redirect_to @profile, notice: 'Profile was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @profile.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /profiles/1
  # DELETE /profiles/1.json
  def destroy
    @profile = Profile.find(params[:id])
    @profile.destroy

    respond_to do |format|
      format.html { redirect_to profiles_url }
      format.json { head :no_content }
    end
  end
 end

ルート.rb

BaseApp::Application.routes.draw do


  resources :friendships

  resources :profiles

  #get "users/show"

  devise_for :users, :controllers => { :registrations => "registrations" }
  resources :users

  match '/show', to: 'profile#show'




  match '/signup',  to: 'users#new'

  root to: 'static_pages#home'

  match '/', to: 'static_pages#home'

  . . .
4

2 に答える 2

0

実際のオブジェクトなしでメソッドを呼び出そうとすると、「メソッドが定義されていません」というメッセージが表示されます。

メソッドが定義されていることを意味しますが、「nil」があり、それを呼び出そうとしていますが、そのメソッドは「nil」オブジェクトには存在しません。

実際のユーザー テーブルを確認してください。一緒に作業するユーザーが必要です。いくつかあることを確認してください。

必要に応じて、( でscript/rails console) を使用してユーザーを作成できます。

User.new(:name=>'fred', :password =>'pword', :password_confirmation => 'pword' )

これをファイルに配置して、アプリケーションを新しいマシンに初めてセットアップするときにdb/seeds.db実行できるようにすることもできます。rake db:seed

于 2012-10-01T11:31:07.207 に答える
0

@usersに設定していませんProfilesController#show

for object in collectionを呼び出すだけcollection.each do |object|です。これが、得られる理由ですundefined method 'each' for NilClass(また、このような紛らわしいエラーが発生するため、一般的にその構文の使用が推奨されない理由でもあります)。

profile_controller.rb

def show
  @users = User.all
  #...
end
于 2012-10-01T03:25:19.390 に答える