Reputation: 457
I'm following this tutorial https://www.railstutorial.org/book/following_users#top and am at step 12.14. I've followed each step except the ones adding test data because I'm using this tutorial to help me learn to develop a follower following feature on my own project.
Here is the error message from my console:
rake aborted!
NoMethodError: undefined method `each' for nil:NilClass
/Users/alexanderkehaya/Desktop/wewrite/db/seeds.rb:13:in
Any ideas what I'm doing wrong/missing? Edit: How do I get the seed data to rake successfully?
Thanks for the help.
Here is my data:
ActiveRecord::Schema.define(version: 20141030023857) do
create_table "collaborators_stories", id: false, force: true do |t|
t.datetime "created_at"
t.datetime "updated_at"
t.integer "collaborator_id"
t.integer "story_id"
end
create_table "lines", force: true do |t|
t.string "text"
t.integer "score", default: 0
t.integer "depth", default: 0
t.integer "previous_line_id"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id"
t.integer "story_id"
end
create_table "relationships", force: true do |t|
t.integer "follower_id"
t.integer "followed_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "relationships", ["followed_id"], name: "index_relationships_on_followed_id"
add_index "relationships", ["follower_id", "followed_id"], name: "index_relationships_on_follower_id_and_followed_id", unique: true
add_index "relationships", ["follower_id"], name: "index_relationships_on_follower_id"
create_table "stories", force: true do |t|
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "users", force: true do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at"
t.datetime "updated_at"
t.string "provider"
t.string "uid"
t.string "name"
t.string "profile_image_url"
end
add_index "users", ["email"], name: "index_users_on_email", unique: true
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
Here is my user.rb file:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :omniauthable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :lines
has_many :active_relationships, class_name: "Relationship",
foreign_key: "follower_id",
dependent: :destroy
has_many :passive_relationships, class_name: "Relationship",
foreign_key: "followed_id",
dependent: :destroy
has_many :following, through: :active_relationships, source: :followed
has_many :followers, through: :passive_relationships, source: :follower
has_and_belongs_to_many :stories, :foreign_key => :collaborator_id, :join_table => :collaborators_stories
def profile_image_uri(size = "mini")
# parse_encoded_uri(insecure_uri(profile_image_uri_https(size))) unless @attrs[:profile_image_url_https].nil?
unless self.provider == "facebook"
self.profile_image_url.sub! "normal", size unless self.profile_image_url.nil?
else
self.profile_image_url
end
end
#Follows a user.
def follow(other_user)
active_relationships.create(followed_id: other_user.id)
end
# Unfollows a user.
def unfollow(other_user)
active_relationships.find_by(followed_id: other_user.id).destroy
end
# Returns true if the current user is following the other user.
def following?(other_user)
following.include?(other_user)
end
def self.find_for_twitter_oauth(auth, signed_in_resource=nil)
user = User.where(:provider => auth.provider, :uid => auth.uid).first
if user
if user.profile_image_url != auth.extra.raw_info.profile_image_url
user.update_attribute(:profile_image_url, auth.extra.raw_info.profile_image_url)
end
return user
else
registered_user = User.where(:email => auth.uid + "@twitter.com").first
if registered_user
return registered_user
else
user = User.create(name:auth.extra.raw_info.name,
provider:auth.provider,
profile_image_url:auth.extra.raw_info.profile_image_url,
uid:auth.uid,
email:auth.uid+"@twitter.com",
password:Devise.friendly_token[0,20],
)
end
end
end
def self.find_for_facebook_oauth(auth, signed_in_resource=nil)
user = User.where(:provider => auth.provider, :uid => auth.uid).first
if user
if user.profile_image_url != auth.info.image
user.update_attribute(:profile_image_url, auth.info.image)
end
return user
else
registered_user = User.where(:email => auth.info.email).first
if registered_user
return registered_user
else
user = User.create(name:auth.extra.raw_info.name,
provider:auth.provider,
profile_image_url:auth.info.image,
uid:auth.uid,
email:auth.info.email,
password:Devise.friendly_token[0,20],
)
end
end
end
end
Here is my relationships.rb file:
class Relationship < ActiveRecord::Base
belongs_to :follower, class_name: "User"
belongs_to :followed, class_name: "User"
validates :follower_id, presence: true
validates :followed_id, presence: true
end
EDIT: I added my seeds file:
users = User.all
user = users.first
following = users[2..50]
followers = users[3..40]
following.each { |followed| user.follow(followed) }
followers.each { |follower| follower.follow(user) }
Upvotes: 0
Views: 967
Reputation: 6349
The error message explains itself. undefined method 'each' for nil:NilClass
tells you that you are tryiing to send each
method to a nil
object. It can be deduced that following
and/or followers
, on which you are calling each
, are nil
, not an ActiveRecord Relation
object you hope it to be.
Did you remember to create User objects in your seed file? If your seed file is just as shown in your question, it wouldn't work because User
model does not have any objects in it.
You must create them first as shown in here listing 12.14. You can either use FactoryGirl like Railstutorial does, or just plain Ruby.
Upvotes: 1