Rails 3 seed file loads everything but data for User model - ruby-on-rails-3

When I run rake db:seed for my Rails 3 app, all of the seed data except for the User data loads into my database. Here's a sample User that I create in my seeds file:
me = User.create(:email => 'me#gmail.com', :password => 'test', :profile => my_profile)
The profile for my user - my_profile = Profile.create(..) - loads. As do all of my other models. Is this the cause of my seeds.rb setup, or something in my User.rb model?
I'm using PostgreSQL, running ruby 1.9.2 and Rails 3.0.5.
UPDATE: In my seed file, if I add an exclamation point after create I get a validation error on my email address:
Validation failed: Email is too short (minimum is 5 characters), Email is invalid
So that gets me closer to figuring out the issue. I'll mark this as answered and ask a new question about the validation error.

Try using .create! instead to make it throw and exception if something is going wrong with validation.

Related

Assigning a random password while using Devise

Here's a breakdown of the situation -
Desired behavior: user can sign_up through Devise gem by providing their email address only. Web app generates and db stores a temporary password, unknown to user.
Logic: This is meant to be a 'gradual sign-up' process to a web application still under construction (we want to begin capturing potential users without providing access to the web app as it's still in partial development). The email is to be used for communication purposes until final release.
Problem: Devise gem requires user to input email && password during sign_up process. We've found no obvious way to circumvent the dual requirement. User failing to provide password generates error.
Potential solution: After searches and many tries, this seems to be the closest alternative (found here).
generated_password = Devise.friendly_token.first(8)
user = User.create!(:email => email, :password => generated_password)
Question: While this potential solution makes sense, we're REALLY new to this and don't understand in which file to place this code within the Devise configuration, and how to call it.
All help appreciated.
LM
OK, I kept digging until I found what I was looking for (here) - maybe it can help you too.
In your model:
before_validation :generate_password, :on => :create
def generate_password
o = [('a'..'z'), ('A'..'Z'), (0..9)].map{|i| i.to_a}.flatten
self.password = self.password_confirmation = (0..16).map{ o[rand(o.length)] }.join if self.password.blank?
end

validates_inclusion_of Rails 3 with a query not working as expected

I am newish to Rails and i am facing a prblem. I have
Models
Model1
id: integer
account_id: integer
Account
id: integer
I have a validation in the Model1 as follows,
Model Code:
validates :account_id, :inclusion => { :in => Account.find(:all).collect(&:id)}
I use a dropdown for
View Code:
<%= f.select :account_id, #accounts.collect {|acc| [acc.name, acc.id]}, {:prompt => 'Select Account' }, { :selected => #defaultaccount, :class => 'selectwidth' } %>
I am using client side validations to validate the fields before submitting the form. I am using Heroku to deploy my app.
I create an account first and then from the form i try to create a new model1. The drop down is populated with all the accounts that i have. Then i select an account that i created from the dropdown, the client side validations comes into effect and says "is not valid" which is the error message for validates_inclusion_of as if the account never exists. Not sure what ishappening and i checked the database and the account is created which is why the dropdown is loaded with accounts in the first place.
I change the validates_inclusion_of to rails 3 validates :account_id, :inclusion => { :in => {} } syntax and redeploy. Now i try to select that account in the new model1 form, The drop down does not show an error for the account that was previously created.
So then i created a new account and tried to create a new model1 for the new account the validation failure resurfaces.
So its like a cache issue ? Is it a client side validations issue ? I did everything i can to try and find what the issues is but i am out of ideas on what is happening.
So everytime i create an account it expects me redeploy which kills what the application does. How do i get rid of this problem ? Not really sure what is happening.
Config,
Rails 3
Deployed in Heroku
uses Asset pipeline
Gems:
Client Side Validations
Kaminari
It's not working as you want because the :in => Account.find(:all).collect(&:id) it's evaluated just one time in production mode, when Rails loads the class. I confess I don't understand the reason behind such a validation. Anyway, you have to use a custom validator if you really want to achieve that.
Currently, the statement gets executed once the server is started (as you correctly realized). You'll need to wrap it in a lambda, so it gets executed everytime the validation is done.
1.8.7 Syntax:
validates :account_id, :inclusion => { :in => lambda {Account.find(:all).collect(&:id)}}
1.9.2 Syntax:
validates :account_id, :inclusion => { :in => ->{Account.find(:all).collect(&:id)]}

How to use #valid_attributes in a before block in rails 3 and rspec?

I'm trying different blogs with examples of Rails 3 and RSpec. Yes it's on Windows, so the answer isn't not using Windows. No choice in that. Moving on...
I am able to run the spec either with rspec spec or rake spec:models so that seems fine. However if I try to use a before block with attributes it fails on creating a Person class with those attributes. The other tests are just there to show spec can run.
Made a Person model then updated the spec
\myapp\spec\models\person_spec.rb
require 'spec_helper'
describe Person do
before(:each) do
#valid_attributes = {
:first_name => "Foo",
:last_name => "Bar"
}
end
it "should create a new instance given valid attributes" do
Person.create!(#valid_attributes)
end
it "can be instantiated" do
Person.new.should be_an_instance_of(Person)
end
it "can be saved successfully" do
Person.create.should be_persisted
end
#pending "add some examples to (or delete) #{__FILE__}"
end
Here's the output of rake spec:models command
C:\Users\laptop\Documents\Sites\myapp>rake spec:models
C:/Ruby193/bin/ruby.exe -S rspec ./spec/models/person_spec.rb
Person
←[31m should create a new instance given valid attributes (FAILED - 1)←[0m
←[32m can be instantiated←[0m
←[32m can be saved successfully←[0m
Failures:
1) Person should create a new instance given valid attributes
←[31mFailure/Error:←[0m ←[31mPerson.create!(#valid_attributes)←[0m
←[31mActiveRecord::UnknownAttributeError:←[0m
←[31munknown attribute: first_name←[0m
←[36m # ./spec/models/person_spec.rb:13:in `block (2 levels) in <top (required)>'←[0m
Finished in 0.074 seconds
←[31m3 examples, 1 failure←[0m
Failed examples:
←[31mrspec ./spec/models/person_spec.rb:12←[0m ←[36m# Person should create a new instance given valid attributes←[0m
rake aborted!
C:/Ruby193/bin/ruby.exe -S rspec ./spec/models/person_spec.rb failed
So two out of three passed just not the one with attributes.
Anything in particular that would need to be setup for a before block to run or how are attributes passed in a test with Rails 3?
Also is there a way to get rid of those ]31m and such printouts for each spec line?
Thanks
It would appear from the error that ActiveRecord can't find the attribute :first_name that you are passing as part of #valid_attributes. That is, the problem isn't with how you are using RSpec, but with the attributes you are expecting a valid model to contain.
Check that you have a :first_name field or attribute on the Person model - and verify the exact spelling (:first_name vs :firstname or some other variation)
I should update this with the answer.
The Person model did in fact contain first_name and last_name but as noted by two people above the error I was receiving pointed to ActiveRecord not finding it.
In Windows, running rake db:migrate two or three times eventually fixed it even though it wasn't missing in the model.
If you're stuck on Windows dev, this may be a good thing to know!
I finally was able to put Lubuntu on a VirtualBox on Windows 7 and it ran fine and since then I have proceeded with other examples from there.
Cheers

Paperclip not saving files with save()

I have a little problem with paperclip saving the data passed through the form...
If I'm trying to save the record with .save() it won't save.. When I look in the server/log there are no errors or warnings for the paperclip gem :-/
# trying to save the record with save() -- not working :-/
def create
#baan_import = BaanImport.new(params[:baan_import])
if #baan_import.save
redirect_to(baan_imports_url)
else
render 'new'
end
end
Server-log: (using .save() in controller)
https://gist.github.com/1327347
I just don't get it why it's working if I'm using .create instead of .save()
# trying to save the record with Model.create() -- working!
def create
#baan_import = BaanImport.create(params[:baan_import])
redirect_to(baan_imports_url)
end
Server-log: (using .create() in controller)
https://gist.github.com/1327359
Can some one explain me why it's working with create and not with save??
Thanks,
Michael
Can you show us the BaanImport model. My first guess is you're possibly missing baan_upload in attr_accessible on your model, and as a result, Rails will not let you mass assign the file parameter for upload.
Can you also confirm (would appear as though it's properly set up) that your form has html => {:multipart => true} as an option?

Failing to test Devise with Capybara

I'm building a Rails 3 app using Devise, with Capybara for UI testing. The following test is failing:
class AuthenticationTest < ActionController::IntegrationTest
def setup
#user = User.create!(:email => 'test#example.com',
:password => 'testtest',
:password_confirmation => 'testtest')
#user.save!
Capybara.reset_sessions!
end
test "sign_in" do
# this proves the user exists in the database ...
assert_equal 1, User.count
assert_equal 'test#example.com', User.first.email
# ... but we still can't log in ...
visit '/users/sign_in'
assert page.has_content?('Sign in')
fill_in :user_email, :with => 'test#example.com'
fill_in :user_password, :with => 'testtest'
click_button('user_submit')
# ... because this test fails
assert page.has_content?('Signed in successfully.')
end
end
... but I have no idea why. As you can see from the code, the user is being created in the database; I'm using the same approach to create the user as I did in seeds.rb.
If I run the test through the debugger, I can see the user in the database and verify that the page is loading. But still the authentication fails; I can verify this because if I change the assertion to test for the failure case, the test passes:
# verify that the authentication actually failed
assert page.has_content?('Invalid email or password.')
I'm used to Rails 2, & using Selenium for this sort of testing, so I suspect I'm doing something daft. Could someone please point me in the right direction here?
I was having the same issue and found a thread with a solution:
RSpec.configure do |config|
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
For the DatabaseCleaner stuff to work you'll need to include the database_cleaner gem. If you haven't used it before, you may need to rake db:test:prepare before rerunning your tests. I hope this works for you, too!
I've run into a similar problem before. Setting the password directly has some weird effects because it's supposed to be encrypted and stored with a salt--sometimes it works for me and other times it doesn't. I have a hard time remembering which specific cases were problematic. I'd recommend the following, in this order (for simplicity)
Verify that the password field is getting filled in properly and passed as the right param (not necessary if you're using Devise's autogenerated view and haven't touched it)
if your site can run in development mode (i.e. no log in bugs), then just boot it up and log in manually
If not, insert debugger as the first line in your sessions_controller. Then check params and make sure the password is correct and in params[:user][:password].
If you didn't override Devise's sessions_controller, then you can find your Devise path with bundle show devise. Then look for the create action within (devise path)/app/controllers/devise/sessions_controller.rb
Change your test setup to create a user through the web interface, to ensure the password gets set properly, then try running your test again
I had the same issue with a setup fairly similar to yours. In my case, switching to ActiveRecord sessions in the initializer solved the problem.
Additionally, make sure you call #user.skip_confirmation! if you are using the "confirmable" module in devise.