Don't stop rake task if raise an error - ruby-on-rails

I have simple rake file.
It imports data from the .xls file to the database.
But some of the data is invalid. Then data is invalid rake stop excecuting script.
But I wan to just skip this row and try with the next.
Part of my code:
data.each do |row|
username = row[0].slice!(0..2) + row[1].slice!(0..2) + rand(100).to_s
username.downcase
password = "pass1234"
User.create!(
email: row[2].downcase,
username: username,
first_name: row[0],
last_name: row[1],
expiration_date: row[3],
password: password,
password_confirmation: password)
p 'done'
end
The error is about the validation, eg.:
rake aborted!
ActiveRecord::RecordInvalid: Validation failed: Expiration date must be after 2015-10-27
Script is stopped and valid records are not added.

Wrap it in a begin/rescue block.
data.each do |row|
begin
username = row[0].slice!(0..2) + row[1].slice!(0..2) + rand(100).to_s
username.downcase
password = "pass1234"
User.create!(
email: row[2].downcase,
username: username,
first_name: row[0],
last_name: row[1],
expiration_date: row[3],
password: password,
password_confirmation: password)
p 'done'
rescue => e
# log exception or ignore it.
end
end
Note that this works because the default rescue is for StandardError. Since ActiveRecord::RecordInvalid < StandardError. It will be 'catched'.
You could rescue the specific error first if you only want to do something with those specific errors.
(For reference also see the API: http://ruby-doc.org/core-2.2.0/Exception.html)

Related

Problems with 'seeding' data to different users

I would like to seed some data to my wiki model user the 'faker gem'. I have created three users and would like to 'spread' 20 wikis over them.
I installed the faker gem, run bundle and set up my seedfile like this:
require 'faker'
# Create an admin user
admin = User.new(
email: 'admin2#example.com',
password: 'helloworld',
role: 'administrator'
)
admin.save!
# Create a moderator
moderator = User.new(
email: 'moderator2#example.com',
password: 'helloworld',
role: 'moderator'
)
moderator.save!
# Create a member
member = User.new(
email: 'member2#example.com',
password: 'helloworld'
)
member.save!
users = User.all
15.times do
Wiki.create!(
title: Faker::Lorem.sentence,
body: Faker::Lorem.paragraph
user: users.sample
)
end
wikis = Wiki.all
puts "Seeds finished"
If I run this I get an error:
SyntaxError: /Users/marcvanderpeet/Projects/bloc/blocipedia/db/seeds.rb:37: syntax error, unexpected tIDENTIFIER, expecting ')'
user: users.sample
I dont understand why I get this error as when Im running rails c I can just type in a user:
2.1.5 :001 > u = Wiki.new
=> #
Any clues on how to fix this?
You have a syntax error: the line
body: Faker::Lorem.paragraph
should end with a comma.
Already got it, forgot a ','. Devil is in the details!

How to authenticate users using rubycas-server with multi-field?

I used rubycas-server to build an sso systems, using devise to do the user's system, but now my question is, rubycas-server only one field like 'email' , I want to use 'email' / 'tel' / 'nickname' for user login. no more info in wiki
authenticator:
class: CASServer::Authenticators::SQLBcrypt
database:
adapter: mysql2
database: xxxx
username: root
password: xxxx
host: localhost
user_table: users
username_column: email # tel/nickname
password_column: encrypted_password
sorry about my poor English! help me, thanks very much!
I'm affraid it woulnd't be possible. As can be seen in the official repository, this authenticator just matches given column name with user name:
def matching_users
results = user_model.find(:all, :conditions => ["#{username_column} = ?", #username])
results.select { |user| BCrypt::Password.new(user.send(password_column.to_sym)) == #password }
end
For your case the best idea would be to write custom authenticator that matches email/tel/nickname. This is however very tough login name though, consider some more user friendly.
Modify the following code in rubycas-server/lib/casserver/authenticators/sql_bcrypt.rb
def matching_users
results = user_model.find(:all, :conditions => ["#{username_column} = ?", #username])
results.select { |user| BCrypt::Password.new(user.send(password_column.to_sym)) == #password }
end
to
def matching_users
if username_column.include?(',')
columns = username_column.split(',')
sql = ''
conditions = []
columns.each do |field|
if sql.length != 0
sql += ' or '
end
sql += "#{field} = ?"
conditions << #username
end
conditions.unshift(sql)
else
conditions = ["#{username_column} = ?", #username]
end
results = user_model.find(:all, :conditions => conditions)
results.select { |user| BCrypt::Password.new(user.send(password_column.to_sym)) == #password }
end
then u can use mutli-fieds in config.yml like this:
authenticator:
class: CASServer::Authenticators::SQLBcrypt
database:
adapter: mysql2
database: test
username: root
password: map
host: localhost
user_table: users
username_column: email,nickname,tel
password_column: encrypted_password

Rails 4.1 Devise 3.3 column users.password does not exist

I want to create a user manually through the console as such:
User.find_or_create_by(email: "user#mail.com", first_name: "Stan", last_name: "Smith", password: "password", password_confirmation: "password", confirmed_at: Time.now)
I have done this many times in past projects but this time it's not working. It is not picking up the Devise password model attribute so this is the error I get:
PG::UndefinedColumn: ERROR: column users.password does not exist
I have Rails 4.1.4 and Devise 3.3.0. Did something change in the latest versions?
Thanks.
Instead of User.find_or_create_by you should be using User.create.
Devise accepts a password and password confirmation on creation but the actual table only has a column called encrypted_password.
The "find" portion of User.find_or_create_by is looking for a column called "password" which doesn't exist.
Still if you want to use find_or_create_by, it accepts block:
User.find_or_create_by(email: "user#mail.com", first_name: "Stan", last_name: "Smith") do |user|
user.password = "password"
user.confirmed_at = Time.now
end

Nested attributes in rake task

I'm trying to create a rake task to populate my DB. I need to to create 1 user with a specifc set of deatails and 99 other randomly genraterated . The details that are required are for two Models at the same time, similar to a form with nested attribues. My model uses an after_create call back to create and link a users to a team. The team name by default is the users name
the current code that I have used it producing errors
sample_data.rake
namespace :db do
desc "Fill database with sample data"
task populate: :environment do
user = User.create!(:profile_attributes => { name: Forgery::Name.full_name },
email: "test#example.com",
password: "123qwe",
password_confirmation: "123qwe")
99.times do |n|
:profile_attributes => { name: Forgery::Name.full_name },
email = Forgery::Internet.email_address
password = "password"
user = User.create!(email: email,
password: password,
password_confirmation: password)
end
end
end
Model that relys on the nested attibute.
class User < ActiveRecord::Base
after_create :set_user_on_team
private
def set_user_on_team
self.create_owned_team(:name => self.profile.name ).users << self
end
end
error message
rake aborted!
/lib/tasks/sample_date.rake:9: syntax error, unexpected tASSOC, expecting keyword_end
:profile_attributes => { name: Forgery::Name.full_name },
^
/lib/tasks/sample_date.rake:9: syntax error, unexpected ',', expecting keyword_end
I noticed some syntax errors in the 99.times block. You could try it like this:
99.times do |n|
profile_attributes = { name: Forgery::Name.full_name }
email = Forgery::Internet.email_address
password = "password"
user = User.create!(profile_attributes: profile_attributes, #my assumption
email: email,
password: password,
password_confirmation: password)
end

Create a devise user from Ruby console

Any idea on how to create and save a new User object with devise from the ruby console?
When I tried to save it, I'm getting always false. I guess I'm missing something but I'm unable to find any related info.
You can add false to the save method to skip the validations if you want.
User.new({:email => "guy#gmail.com", :roles => ["admin"], :password => "111111", :password_confirmation => "111111" }).save(false)
Otherwise I'd do this
User.create!({:email => "guy#gmail.com", :roles => ["admin"], :password => "111111", :password_confirmation => "111111" })
If you have confirmable module enabled for devise, make sure you are setting the confirmed_at value to something like Time.now while creating.
You should be able to do this using
u = User.new(:email => "user#name.com", :password => 'password', :password_confirmation => 'password')
u.save
if this returns false, you can call
u.errors
to see what's gone wrong.
When on your model has :confirmable option this mean the object user should be confirm first. You can do two ways to save user.
a. first is skip confirmation:
newuser = User.new({email: 'superadmin1#testing.com', password: 'password', password_confirmation: 'password'})
newuser.skip_confirmation!
newuser.save
b. or use confirm! :
newuser = User.new({email: 'superadmin2#testing.com', password: 'password', password_confirmation: 'password'})
newuser.confirm!
newuser.save
If you want to avoid sending confirmation emails, the best choice is:
u = User.new({
email: 'demo#greenant.com.br',
password: '12feijaocomarroz',
password_confirmation: '12feijaocomarroz'
})
u.confirm
u.save
So if you're using a fake email or have no internet connection, that'll avoid errors.
None of the above answers worked for me.
This is what I did:
User.create(email: "a#a.com", password: "asdasd", password_confirmation: "asdasd")
Keep in mind that the password must be bigger than 6 characters.

Resources