How to store obtain id based on name in Rails? - ruby-on-rails

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

Related

Model is Invalid Because Foreign Key Does Not Exist When It's Created

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

Recreate devise users table from excel

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?

How to get multiple values of a record with map

In my application I can have multiple accounts and accounts can have multiple emails. I have a method that counts all the unique email from every account, but that is not what I want however.
Instead I want to return all the unique email from just one account NOT all, as the method is currently doing.
Here is my current method:
class AccountEmails
def self.count
accounts = Account.all
alert = accounts.map do |a|
a.users.first.alert_email.split(",")
end
billing = accounts.map do |a|
a.users.first.billing_email.split(",")
end
user = accounts.map do |a|
a.users.first.email.split(",")
end
snitch = accounts.map do |a|
a.snitches.map { |s| s.alert_email.split(",") }
end
[alert, billing, user, snitch].flatten.uniq.count
end
end
This will return all the email that are unique from all the accounts. I want to return all the unique email for each account, so account 1 could have four unique email and account 2 could have five unique email.
It sounds like you're saying you want a single method that gives you all the unique emails for each account. If I'm understanding you, I would do something like this:
class Account
def all_emails
# I'm assuming here that you actually only want the unique
# emails on the first user for each account
user = self.users.first
[
user.alert_email.split(","),
user.billing_email.split(","),
user.email.split(","),
self.snitches.map{|snitch| snitch.alert_email.split(",") }
].flatten
end
def unique_emails
all_emails.uniq
end
end
class AccountEmails
def self.unique
Account.all.includes(:snitches).map do |account|
account.uniq_emails
end
end
def self.count
uniq.flatten.count
end
end

Searching table by id and other fields in Rails

I'm trying to do a search on the following fields in my rails model: id, description, notes, and customer_name.
In my model TechServiceSpecial:
def self.search(params)
q = "%#{params[:search].try(:strip).tr('%', '')}%"
#build up general search
general_search_fields.reduce(nil) do |running_query, field|
if field =~ /id/
main_check = arel_table[field].eq(q.to_i)
else
main_check = arel_table[field].matches(q)
end
if running_query.nil?
main_check
else
running_query.or(main_check)
end
end
end
private
def self.general_search_fields
%i(id description notes customer_name)
end
In my controller (I'm using Kaminari for pagination):
def search
specials = TechServiceSpecial.where(TechServiceSpecial.search(params))
#tech_service_specials = specials.page(params[:page]).per(200)
render 'index'
end
This will not find a record if I search using an id. So, if I have a record with id of 1005, that record will not be returned in the search results for '1005', unless the description, notes or customer_name also happen to have 1005 in them. Any record that happens to have 1005 in the description, notes, or customer_name will be returned.
So, I tweaked the controller to look like this:
def search
specials = TechServiceSpecial.where(TechServiceSpecial.search(params))
specials.merge(TechServiceSpecial.where(id: params[:search].to_i))
#tech_service_specials = specials.page(params[:page]).per(200)
render 'index'
end
But I get the same results. Will not return the record with an id of 1005.
How can I make this return a record that has the id that equals the string I'm searching with?
In your TechServiceSpecial.search method:
q = "%#{params[:search].try(:strip).tr('%', '')}%"
...
if field =~ /id/
main_check = arel_table[field].eq(q.to_i)
...
the value for the id will always be 0, since q starts with a "%".
You should set q to params[:search].to_i if the field is id.

Rake db:seed not associating a created object to it's parent model correctly?

I have a User model which has_one Library which has_many Books.
In my seeds file I do this:
user1 = User.new
user1.email = "test#email.com"
user1.name = "testname"
user1.password = "password"
user1.library = Library.new
user1.library.save!
book1 = Book.create!(hash_of_attributes)
user1.library.books << book1
puts "book1 library_id " + book1.library_id.to_s
user1.save!
the line puts "book1 library_id " + book1.library_id.to_s clearly outputs the value of 1, so we know the library_id attribute is set to 1 on the newly created Book model.
However, after running rake db:seed, I run rails console and do:
User.first.library.books
only to find
<ActiveRecord::Associations::CollectionProxy []>
And running Book.first shows
library_id: nil
So the book was created except it wasn't properly associated to my library, which is properly associated to my user model.
What is going on?
Running Rails 4.1.6
user1 = User.new
user1.email = "test#email.com"
user1.name = "testname"
user1.password = "password"
user1.save!
First of all you need to save user for it's id. Then ....
user1.library = Library.new
library1 = user1.library.save!
book = Book.create!(hash_of_attributes)
book1 = library1.books << book
puts "book1 library_id " + book1.library_id.to_s
The problem is your user does not have an id by the time you're trying to make associations on it. Just a quick update to the script and you should be good to go:
user1 = User.create(email: "test#email.com", name: "testname", password: "password")
user1.library.create
user1.library.books.create(hash_of_attributes)

Resources