I want to have my database tables in excel as a backup so I am able to reseed my database from scratch.
So far everything works OK, except the devise users model.
The code looks like this:
*users.rb*
def self.import(file)
spreadsheet = Roo::Spreadsheet.open(file.path)
header = spreadsheet.sheet(0).row(1) #sheet(0) is the first sheet
(2..spreadsheet.sheet(0).last_row).each do |i|
row = Hash[[header, spreadsheet.sheet(0).row(i)].transpose]
user = find_by(fullname: row["Fullname"]) || new
user.update_fields(row)
end
end
def update_fields(fields)
self.fullname = fields["Fullname"]
self.email = fields["Εmail"]
self.role = fields["Role"]
self.encrypted_password = fields["Enc. Password"]
self.reset_password_token = fields["Password Token"]
self.confirmed_at = fields["Confirm. Date"]
self.confirmation_sent_at = fields["Confirm. SentAt"]
self.confirmation_token = fields["Confirm. Token"]
self.save!
end
When the save is executed I get a rollback error that the Password cannot be blank. I am confused because no password seems to be kept in the database. What it seems to be saved is an encrypted password which I am importing from excel (so it is not blank).
Any ideas?
Related
I have a user table and 2 other tables that each have foreign keys to the user table's id field. WhenI create a user, I would like to initialize a record in all three tables, but I'm having trouble doing so. The user record is ultimately created, but not the records in the other two tables. After some debugging, I discovered those models were not saved because they were invalid. The error message said, User must exist. I'm trying to accomplish the initialization inside the create method:
def create
logger.info "inside sessions create"
# how do I save user first, THEN create a record associated with user in 2 tables ?
User.where(:id => auth_hash.uid).first_or_create do |user| # finds the matching record in users table
user.name = auth_hash.info.name
user.id = auth_hash.uid
user.token = auth_hash.credentials.token
user.secret = auth_hash.credentials.secret
#tweetstore = Tweetstore.new() # Record I'd like to save in Table with Foreign KEY
#tweetidstore = Tweetidstore.new() # Another Record I'd like to save in a Table with Foreign KEY
istsvalid = #tweetstore.valid? # returns false
istsidvalid = #tweetidstore.valid?
error = #tweetstore.errors.full_messages #USER MUST EXIST
#tweetstore[:user_id] = auth_hash.uid
#tweetidstore[:user_id] = auth_hash.uid
is_tweetstore_save = #tweetstore.save # false
is_tweet_idstore_save = #tweetidstore.save
end
session[:user_id] = auth_hash.uid
redirect_to '/'
end
How do I restructure my code so that User will exist by the time I initialize the other dependant tables? I tried bypassing the problem by adding the optional parameter to the models (eg belongs_to :user, optional: true) but then I get another error: QLite3::ConstraintException: FOREIGN KEY constraint failed I'm a newbie at Ruby so please ELI5
Consider using transactions when you need to create dependent models. When one of the insert fails, let everything that were inserted to DB before that get rollbacked.
Also you should be using user.id and not auth_hash.uid
ex.
#tweetstore[:user_id] = auth_hash.uid
should be
#tweetstore[:user_id] = user.id
Also
istsvalid = #tweetstore.valid? # returns false its false because it's not yet saved into database.
try this:
def create
...
#user.id = auth_hash.uid <---- do not set this
...
#tweetstore[:user_id] = user.id
#tweetidstore[:user_id] = user.id
...
i ditched the first_or_create method and just included a condition for the existence of the record. i'm not sure when user is saved in the where block i used above, so i explicitly saved it before saving records in my dependent tables.
if !User.exists?(auth_hash.uid)
#user = User.new()
#user.name = auth_hash.info.name
#user.id = auth_hash.uid
#user.token = auth_hash.credentials.token
#user.secret = auth_hash.credentials.secret
is_user_save = #user.save
#tweetstore = Tweetstore.new()
#tweetidstore = Tweetidstore.new()
#tweetstore[:user_id] = auth_hash.uid
#tweetidstore[:user_id] = auth_hash.uid
is_tweetstore_save = #tweetstore.save
is_tweet_idstore_save = #tweetidstore.save
end
I am working on an app where I am required to fetch and save the open graph data of a website.
So far I have been able to grab properties such as title, description, url by using this code
before_save :get_meta_from_link
def check_link
begin
#page_link = MetaInspector.new(sanitized_url)
rescue Faraday::ConnectionFailed => e
errors.add(:link, "Oops, can't be processed ATM")
end
end
def get_meta_from_link
page = #page_link
return unless page.to_hash.present?
if page.title.present?
self.title = page.title
end
if page.description.present?
self.description = page.description
end
if page.url.present?
self.url = page.url
end
end
I am using the metainspector gem and trying to grab values such as og:locale, og:type. How can I fetch those values?
This is the link I am using to cross reference values: https://metainspectordemo.herokuapp.com
Ok, so I managed to solve it using
def check_link
begin
#page_link = MetaInspector.new(sanitized_url)
rescue MetaInspector::RequestError => e
errors.add(:link, "you provided is not being read by our system. Please check the link.")
end
end
in my link model
followed by
def get_meta_from_link
page = #page_link
paje = #page_link.meta_tags
return unless page.to_hash.present?
if page.title.present?
self.btitle = page.title
end
end
I'm trying create records in the Pairing table from a CSV file upload. The file given will be in this format
supervisor,student,project_title
Bob,Alice,Web Site
Bob,Charlie,Web Application
Issue is the Pairing table doesn't hold supervisor or student names but rather their IDs, so it would be necessary to search the User table for these given names and select their IDs then create the Pairing with these ids and the given project title.
The code below is giving me a too many redirects error and inserting a null record into the pairings table.
Pairing.rb
def self.import(file)
CSV.foreach(file.path, headers: true) do |row|
supervisorName = row[0]
studentName = row[1]
title = row [2]
supervisorID = User.select(:id).where(name: supervisorName)
studentID = User.select(:id).where(name: studentName)
pair = Pairing.new
pair.supervisor_id = supervisorID
pair.student_id = studentID
pair.project_title = title
pair.save
end
end
Pairings_controller.rb
def new
#pairing = Pairing.new
end
def create
#pairing = Pairing.new(pairing_params)
if #pairing.save
redirect_to pairings_path, :notice => "Pairing Successful!"
else
redirect_to pairings_path, :notice => "Pairing Failed!"
end
end
def import
Pairing.import(params[:file])
redirect_to pairings_path, :notice => "Pairs Imported"
end
The statement User.select(:id).where(name: supervisorName) won't return an integer value as you're expecting. Consider using User.find_by(name: supervisorName).id Instead.
As for too many redirects, make sure that the action matching your pairings_path doesn't redirect back to itself or other actions that may yield circular redirects.
I am work on a maintenance project which consists of imports.
My file:
app/importers/contacts_importer.rb:
require 'csv'
class ContactsImporter < BaseImporter
def import
..............
sales_exec = fetch_value(row, "Sales Exec", :string)
email = fetch_value(row, "Email", :string)
...................
sales_exec_id = nil
if sales_exec.present?
sr = #file_import.account.users.where(initials: sales_exec).first
sales_exec_id = sr.try(:id) if sr.present?
end
sales_exec_id = sales_exec_id
if company.present?
customer = Company.new
customer.name = company
customer.phone = phone
customer.email = email
customer.sales_exec = sales_exec_id
end
end
end
My requirement is I am able to store name, phone and email but could not get sales_exec_id.
Here sales_exec are users which are having role_name (Sales Executive, Product Manager etc) in roles table.
The relation is user has_many roles through user_roles(consists of role_id and user_id).
Is there any way to write query to match sales_exec (which displays Venkat, John etc) in my code with sales_exec_id.
since not having your whole system environment and the csv file, I would suggest two approaches.
if sales_exec.present?
sr = #file_import.account.users.where(initials: sales_exec).first
sales_exec_id = sr.try(:id) if sr.present?
end
add puts sr add see the output in terminal
see the query SQL in terminal and you could debug it in your DB GUI
I'm quite new to Ruby on Rails so please bear with me :)
I'm processing an imported .csv file in Rails and I want to programmatically create new users (I'm using the AuthLogic Gem along with Role Requirement), So Far I'm using:
Example Line:
Steve.Jobs#apple.com, Steve, Jobs, 555-APPLE
Code:
def new_user(line)
params = Hash.new
params[:user] = Hash.new
params[:user]["email"] = line[0]
params[:user]["first_name"] = line[1]
params[:user]["last_name"] = line[3]
params[:user]["phone"] = line[4]
user = User.new(params[:user])
user.save
end
The problem being that this doesn't add a new user, it tries to but fails (DB Begin followed by Rollback), I assume because I'm not filling in all the fields, such as login, password etc.
Do I have to explicitly generate values for these fields?
I came across this same problem yesterday. I'm using the oauth addon though so the login/email are not required fields for me, it was failing on the persistence token not being present which I got around by adding
user.reset_persistence_token
just before calling user.save
Hope that helps a bit. Would be nice to find a cleaner way of doing it.
Ok So I've managed to answer my own question, although not in the most ideal of ways:
def new_user(line)
params = Hash.new
params[:user] = Hash.new
params[:user]["email"] = line[0]
params[:user]["first_name"] = line[1]
params[:user]["last_name"] = line[2]
params[:user]["phone"] = line[3]
#generate random password of length 6
password = ActiveSupport::SecureRandom.base64(6)
#generate username by adding first and last name + 3 random characters
username = (line[1] + line[2])
username = username + ActiveSupport::SecureRandom.base64(3)
params[:user]["login"] = username
params[:user]["password"] = password
params[:user]["password_confirmation"] = password
#check to see if user already exists
#existing_user = User.find_by_email(line[0])
if(#existing_user)
#user exists
#do nothing
else
#user is brand new
#new_user = User.new(params[:user])
#new_user.reset_persistence_token
if(#new_user.save)
#new_user = User.find_by_email(line[0])
#user saved successfully
else
#a problem occurred
flash[:errors] = #new_user.errors
end
end
end