简体   繁体   中英

Can't create user, “undefined method `save' for nil:NilClass” using Devise in Rails 4

When trying to create a new Person I receive the following error on the line if @persons.save :

NoMethodError in PeopleController#create, undefined method `save' for nil:NilClass

Any thoughts on how to fix would be much appreciated, thanks.

Controller

  # GET /people/new
  def new
    @person = current_user.person.build
  end

  # GET /people/1/edit
  def edit
  end

  # POST /people
  # POST /people.json
  def create
    @person = current_user.person.build(person_params)

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

User model

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  has_many :person

end

Person model

class Person < ActiveRecord::Base
    has_many :user
    has_paper_trail
    acts_as_taggable

    @tags = Person.acts_as_taggable_on :tags

    def admin_permalink
    admin_post_path(self)
  end
end

It seems like you want a relationship where a user can have many people and a person can have many users.

This requires a special association type called has_many through .

Basically a user can be associated to many people and vice versa, :through a third model called a join table.

eg

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  has_many :people, through: :relationships # The model name(person) is pluralised for has_many associations

end

class Person < ActiveRecord::Base
  has_many :users, through: :relationships # user needs to be pluralised here
  has_paper_trail
  acts_as_taggable

  @tags = Person.acts_as_taggable_on :tags

  ...
end

class Relationship < ActiveRecord::Base # This is the join table
  belongs_to :user
  belongs_to :person
end

This requires you to create the relationship table in the database (Instead of relationship, call it whatever makes the most sense). It needs person_id and user_id integer columns.

In your controller you will then need to use the pluralised version too:

@person = current_user.people.build(person_params)

You should have a good read of the rails association guide . Particularly the has_many through section.

There is another type of association called a has_and_belongs_to_many which may be better for your case. In my experience it often seems like the easier approach but ends up causing headaches compared to has_many through .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM