I am trying to seed my database, but I am running into this error, and as a beginner do not know how to fix it. I'm trying to take a sample of bookmarks and assign them to some of my users. Any ideas why this is throwing an error? Here is the error:
vagrant#rails-dev-box:~/code/bookmarks$ rake db:seed
rake aborted!
NoMethodError: undefined method `sample' for #<Class:0xaa90cf4>
/home/vagrant/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.5/lib/active_record/dynamic_matchers.rb:22:in `method_missing'
/home/vagrant/code/bookmarks/db/seeds.rb:47:in `block (2 levels) in <top (required)>'
/home/vagrant/code/bookmarks/db/seeds.rb:46:in `times'
/home/vagrant/code/bookmarks/db/seeds.rb:46:in `block in <top (required)>'
/home/vagrant/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.5/lib/active_record/relation/delegation.rb:13:in `each'
/home/vagrant/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.5/lib/active_record/relation/delegation.rb:13:in `each'
/home/vagrant/code/bookmarks/db/seeds.rb:45:in `<top (required)>'
/home/vagrant/.rvm/gems/ruby-2.0.0-p481/gems/activesupport-4.0.5/lib/active_support/dependencies.rb:223:in `load'
/home/vagrant/.rvm/gems/ruby-2.0.0-p481/gems/activesupport-4.0.5/lib/active_support/dependencies.rb:223:in `block in load'
/home/vagrant/.rvm/gems/ruby-2.0.0-p481/gems/activesupport-4.0.5/lib/active_support/dependencies.rb:214:in `load_dependency'
/home/vagrant/.rvm/gems/ruby-2.0.0-p481/gems/activesupport-4.0.5/lib/active_support/dependencies.rb:223:in `load'
/home/vagrant/.rvm/gems/ruby-2.0.0-p481/gems/railties-4.0.5/lib/rails/engine.rb:540:in `load_seed'
/home/vagrant/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.5/lib/active_record/tasks/database_tasks.rb:154:in `load_seed'
/home/vagrant/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.5/lib/active_record/railties/databases.rake:181:in `block (2 levels) in <top (required)>'
Tasks: TOP => db:seed
Edit: Here is my seeds.rb file:
require 'faker'
# Create a User
# user = User.new(
# name: 'First Last',
# email: 'firstlast#gmail.com',
# password: 'password',
# )
# user.skip_confirmation!
# user.save
#Create Users
5.times do
user = User.new(
name: Faker::Name.name,
email: Faker::Internet.email,
password: Faker::Lorem.characters(10)
)
user.skip_confirmation!
user.save!
end
users = User.all
#Create Bookmarks
10.times do
Bookmark.create!(
url: Faker::Internet.url
)
end
bookmarks = Bookmark.all
#Create Topics
10.times do
Topic.create!(
name: Faker::Lorem.sentence
)
end
topics = Topic.all
users.each do |user|
3.times do
user.bookmarks << Bookmark.sample
end
end
topics.each do |topic|
3.times do
user.topics << Topic.sample
end
end
puts "Seed finished"
puts "#{User.count} users created"
puts "#{Bookmark.count} bookmarks created"
puts "#{Topic.count} topics created"
Thanks in advance for your help!
whereever you are calling .sample, the object before it is apparently not the correct type of object. It should either be an array or the 'collection' which results when you query your database. Like this...
posts = Post.all
posts.sample would work correctly
any object which is not an array (or like an array) will not have the 'sample' method available for you to use
You cannot call sample on a class as that is not a valid method. The sample method is used for arrays or ActiveRecord::Relation arrays.
For example, each of these would return a random
[0,1,2,3].sample
(0..10).to_a.sample
Post.all.sample
However, something like these examples would give an error.
User.sample
NoMethodError: undefined method 'sample' for #<Class:0x00000007faa378>
(9..199).sample
NoMethodError: undefined method 'sample' for 9..199:Range
Related
namespace :import do
desc "imports data from a csv file"
task :data => :environment do
require 'csv'
CSV.foreach('lib/tasks/file.csv') do |row|
first = row[0]
last = row[1]
city = row[2]
state = row[3]
zipcode = row[4].to_i
email = row[5]
File.create(first: first, last: last, city: city, state: state, zipcode: zipcode, email: email)
end
end
end
When I type in rake import:data the error I end up with is
rake aborted!
NoMethodError: undefined method `create' for File:Class
lib/tasks/import.rake:12:in `block (3 levels) in <top (required)>'
/lib/tasks/import.rake:5:in `block (2 levels) in <top (required)>'
What am i doing wrong?
I have two methods in my Designer class (in my rails app):
def add_specialty(specialty)
specialty_list.add(specialty)
save
end
def add_qualification(qualification)
qualification_list.add(qualification)
save
end
Here are specs I have for them that are passing:
context 'adding specialties' do
it "can add a new specialty" do
expect { designer.add_specialty("interior design") }.to change {designer.specialty_list.count}.by(1)
expect(designer.specialty_list).to include("interior design")
end
end
context 'adding qualifications' do
it "can add a new qualification" do
expect { designer.add_qualification("architect") }.to change {designer.qualification_list.count}.by(1)
expect(designer.qualification_list).to include("architect")
end
end
Now I want to refactor to this implementation:
["specialty", "qualification"].each do |attr|
define_method("add_#{attr}") do |arg|
"#{attr}_list".add(arg)
save
end
end
This fails. I get failures:
1) Designer adding qualifications can add a new qualification
Failure/Error: expect { designer.add_qualification("architect") }.to change {designer.qualification_list.count}.by(1)
NoMethodError:
undefined method `add' for "qualification_list":String
# ./app/models/designer.rb:93:in `block (2 levels) in <class:Designer>'
# ./spec/models/designer_spec.rb:79:in `block (4 levels) in <top (required)>'
# ./spec/models/designer_spec.rb:79:in `block (3 levels) in <top (required)>'
# -e:1:in `<main>'
2) Designer adding specialties can add a new specialty
Failure/Error: expect { designer.add_specialty("interior design") }.to change {designer.specialty_list.count}.by(1)
NoMethodError:
undefined method `add' for "specialty_list":String
# ./app/models/designer.rb:93:in `block (2 levels) in <class:Designer>'
# ./spec/models/designer_spec.rb:72:in `block (4 levels) in <top (required)>'
# ./spec/models/designer_spec.rb:72:in `block (3 levels) in <top (required)>'
# -e:1:in `<main>'
What am I doing wrong in my define_method implementation?
"#{attr}_list" by itself is just the string "specialty_list" or "qualification_list", and strings don't have an add method. I think you want to the send the specialty_list method e.g.
%w{ specialty qualification }.each do |attr|
define_method("add_#{attr}") do |arg|
send("#{attr}_list").add(arg)
save
end
end
Ok: I got it working like this:
["specialty", "qualification"].each do |attr|
define_method("add_#{attr}") do |arg|
instance_eval("#{attr}_list").send(:add, arg)
save
end
end
Not sure why this worked though or if its the right way to do it. Would anyone care to contribute towards a better understanding?
Given the following:
it "sends an email to user" do
subscription = FactoryGirl.create(:subscription, stripe_customer_token: 'bloop')
subscription.expire!
ActionMailer::Base.deliveries.last.to.should == [subscription.user.email]
end
I get:
Failure/Error: ActionMailer::Base.deliveries.last.to.should == [subscription.user.email]
NoMethodError: undefined method `to' for nil:NilClass
# ./spec/models/subscription_spec.rb:113:in `block (3 levels) in <top (required)>'
Which I don't understand, because if I do the same thing in development in console I'll see the email being sent. I have in test.rb config.action_mailer.delivery_method = :test
What could the issue be?
I have been browsing the Rails tutorial with putting together the user account and running tests on it for the project I am working on.
Failures:
1) when email format is invalid should be invalid
Failure/Error: #user.email = invalid_address
NoMethodError:
undefined method `email=' for nil:NilClass
# ./spec/models/user_spec.rb:71:in `block (3 levels) in <top (required)>'
# ./spec/models/user_spec.rb:70:in `each'
# ./spec/models/user_spec.rb:70:in `block (2 levels) in <top (required)>'
2) when email format is valid should be valid
Failure/Error: #user.email = valid_address
NoMethodError:
undefined method `email=' for nil:NilClass
# ./spec/models/user_spec.rb:81:in `block (3 levels) in <top (required)>'
# ./spec/models/user_spec.rb:80:in `each'
# ./spec/models/user_spec.rb:80:in `block (2 levels) in <top (required)>'
Finished in 0.527 seconds
9 examples, 2 failures
Failed examples:
rspec ./spec/models/user_spec.rb:67 # when email format is invalid should be invalid
rspec ./spec/models/user_spec.rb:78 # when email format is valid should be valid
I have no clue what the problem is. I see what it says, but I even C&P the code from the tutorial to double check what I did to ensure everything was type properly.
Here's the user_spec file.
https://gist.github.com/pwz2k/4770845
Here's the user.rb file.
https://gist.github.com/pwz2k/4770854
The fails did not appear until I added the email validation.
Make sure that you're creating #user before you start testing it.. do you have these lines in your User test? (rails tutorial listing 6.16)
before do
#user = User.new(name: "Example User", email: "user#example.com")
end
The error is very clear!. You're setting email to nil class. Which means you're supposed to set the email to a user which we say
#user.email = "something"
The error is complaining there is no user, and there won't be any email for user.
To make is work here is an example code which will help you to fix this issue.
describe "validations" do
before(:each) do
#user = User.new(name: "gates", email: "somename#gmail.com")
end
it "should be invalid" do
invalid_emails = %w{gs#gmail p.com name.gmail.com foo.ymail}
invalid_emails.each do |invalid_email|
#user.email = invalid_email
expect(#user.email).to_not be_valid
end
end
it "should be valid" do
#user.name = "somename"
valid_emails = %w{user#foo.COM A_US-ER#f.b.org frst.lst#foo.jp
a+b#baz.cn}
valid_emails.each do |valid_email|
#user.email = valid_email
expect(#user.email).to be_valid
end
end
end
Please be make sure you've created a fixure for user in your fixures folder.
Hope this helps!
I have few weeks experience or close to a month learning on Ruby on Rails. I hope to understand why I can't get methods via associated objects.
I am attempting to get associated objects attached to user instead of stane alone Profile.new e.g. profile with its methods as seen just below.
user.profile.create
user.profile.create!
user.profile.build
instead i get RSpec error messages. NoMethodError:undefined method `build' for nil:NilClass
Thanks kindly in advance
# == Schema Information
#
# Table name: users
#
# id :integer not null, primary key
# email :string(255)
# created_at :datetime not null
# updated_at :datetime not null
#
class User < ActiveRecord::Base
attr_accessible :email
has_one :profile
before_save { |user| user.email = email.downcase }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
end
.
# == Schema Information
#
# Table name: profiles
#
# id :integer not null, primary key
# given_name :string(255)
# surname :string(255)
# user_id :integer
# created_at :datetime not null
# updated_at :datetime not null
#
class Profile < ActiveRecord::Base
attr_accessible :given_name, :surname #, :user_id
belongs_to :user
validates :user_id, presence: true
end
.
smileymike#ubuntu:~/rails_projects/bffmApp$ bundle exec guard
Guard uses Libnotify to send notifications.
Guard is now watching at '/home/smileymike/rails_projects/bffmApp'
Starting Spork for RSpec
Using RSpec
Preloading Rails environment
Loading Spork.prefork block...
Spork is ready and listening on 8989!
Spork server for RSpec successfully started
Guard::RSpec is running, with RSpec 2!
Running all specs
Running tests with args ["--drb", "-f", "progress", "-r", "/home/smileymike/.rvm/gems/ruby-1.9.3-p194/gems/guard-rspec-0.7.2/lib/guard/rspec/formatters/notification_rspec.rb", "-f", "Guard::RSpec::Formatter::NotificationRSpec", "--out", "/dev/null", "--failure-exit-code", "2", "spec"]...
......FFFFFFFF...............
Failures:
1) Profile
Failure/Error: before { #profile = user.profile.build(given_name: "Michael", surname: "Colin") }
NoMethodError:
undefined method `build' for nil:NilClass
# ./spec/models/profile_spec.rb:23:in `block (2 levels) in <top (required)>'
2) Profile
Failure/Error: before { #profile = user.profile.build(given_name: "Michael", surname: "Colin") }
NoMethodError:
undefined method `build' for nil:NilClass
# ./spec/models/profile_spec.rb:23:in `block (2 levels) in <top (required)>'
3) Profile
Failure/Error: before { #profile = user.profile.build(given_name: "Michael", surname: "Colin") }
NoMethodError:
undefined method `build' for nil:NilClass
# ./spec/models/profile_spec.rb:23:in `block (2 levels) in <top (required)>'
4) Profile
Failure/Error: before { #profile = user.profile.build(given_name: "Michael", surname: "Colin") }
NoMethodError:
undefined method `build' for nil:NilClass
# ./spec/models/profile_spec.rb:23:in `block (2 levels) in <top (required)>'
5) Profile
Failure/Error: before { #profile = user.profile.build(given_name: "Michael", surname: "Colin") }
NoMethodError:
undefined method `build' for nil:NilClass
# ./spec/models/profile_spec.rb:23:in `block (2 levels) in <top (required)>'
6) Profile user
Failure/Error: before { #profile = user.profile.build(given_name: "Michael", surname: "Colin") }
NoMethodError:
undefined method `build' for nil:NilClass
# ./spec/models/profile_spec.rb:23:in `block (2 levels) in <top (required)>'
7) Profile when user_id is not present
Failure/Error: before { #profile = user.profile.build(given_name: "Michael", surname: "Colin") }
NoMethodError:
undefined method `build' for nil:NilClass
# ./spec/models/profile_spec.rb:23:in `block (2 levels) in <top (required)>'
8) Profile accessible attributes should not allow access to user_id
Failure/Error: before { #profile = user.profile.build(given_name: "Michael", surname: "Colin") }
NoMethodError:
undefined method `build' for nil:NilClass
# ./spec/models/profile_spec.rb:23:in `block (2 levels) in <top (required)>'
Finished in 1.56 seconds
29 examples, 8 failures
Failed examples:
rspec ./spec/models/profile_spec.rb:27 # Profile
rspec ./spec/models/profile_spec.rb:28 # Profile
rspec ./spec/models/profile_spec.rb:29 # Profile
rspec ./spec/models/profile_spec.rb:30 # Profile
rspec ./spec/models/profile_spec.rb:33 # Profile
rspec ./spec/models/profile_spec.rb:31 # Profile user
rspec ./spec/models/profile_spec.rb:37 # Profile when user_id is not present
rspec ./spec/models/profile_spec.rb:41 # Profile accessible attributes should not allow access to user_id
Done.
>
.
require 'spec_helper'
describe Profile do
# before do
# This code is wrong but it works
# #profile = Profile.new(given_name: "Michael", surname: "Colin", user_id: user.id)
# end
# but I am attempting to create a profile via User/Profile assoications
let(:user) { FactoryGirl.create(:user) }
before { #profile = user.profile.build(given_name: "Michael", surname: "Colin") }
subject { #profile }
it { should respond_to(:given_name) }
it { should respond_to(:surname) }
it { should respond_to(:user_id) }
it { should respond_to(:user) }
its(:user) { should == user }
it { should be_valid }
describe "when user_id is not present" do
before { #profile.user_id = nil }
it { should_not be_valid }
end
describe "accessible attributes" do
it "should not allow access to user_id" do
expect do
Profile.new(user_id: user_id)
end.should raise_error(ActiveModel::MassAssignmentSecurity::Error)
end
end
end
has_one will give you a build_profile method on user. See http://guides.rubyonrails.org/association_basics.html#has_one-association-reference for more details.
The reason you can't do user.profile.build is that there is no profile, so user.build returns nil and it doesn't make sense to ask nil to build a profile. This is different to the has_many case, where out always returns a collection of things - even when the collection is empty - and you can ask the collection to make another member. It's easy to imagine the has_one accessor returning a non-nil "I'm not here" value, which would enable your scenario, but would have other issues (mainly that such a value would not be falsey, leading to arguably less rubyesque code)