[RUBY] How foreign keys can be saved even with nil

This time, I will explain how to prevent an error even if the foreign key is nil.

information table

id talent_name age user_id
1 Yamada Taro 20 nil
2 Hanako Yamada 20 nil

users table

id login_name
1 nick
2 tom

This time we will use these two tables. The users table and the infomation table form an association. The users table is the parent and the infomation table is the child.

Running via Spring preloader in process 5268
Loading development environment (Rails 5.2.4.4)
[1] pry(main)> Scraping.get_infomation
D, [2020-11-09T06:30:25.470701 #5268] DEBUG -- :    (0.3ms)  SET NAMES utf8,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
D, [2020-11-09T06:30:25.489471 #5268] DEBUG -- :   Infomation Load (1.5ms)  SELECT  `infomations`.* FROM `infomations` WHERE `infomations`.`name` = 'Haru' ORDER BY `infomations`.`id` ASC LIMIT 1
D, [2020-11-09T06:30:25.503981 #5268] DEBUG -- :    (0.1ms)  BEGIN
D, [2020-11-09T06:30:25.524340 #5268] DEBUG -- :    (0.1ms)  ROLLBACK
Return value is: nil

[24, 33] in /home/ec2-user/environment/filebook/app/models/scraping.rb
   24:         names = aaas.at('h1').inner_text  if aaas.at('h1')
   25:         image_urls = personal_page.at('.main_image img').get_attribute('src') if personal_page.at('.main_image img')
   26:         infomation = Infomation.where(name: names).first_or_initialize
   27:         infomation.age = ages
   28:         infomation.image_url = image_urls
   29:         infomation.save
   30:         
   31:         byebug
=> 32:     end
   33: end
(byebug) infomation
#<Infomation id: nil, age: 29, name: "Haru", image_url: "https://images.talent-dictionary.com/uploads/image...", created_at: nil, updated_at: nil>
(byebug) 
Actually user_There is an id column. user_id:nil sorry

It is rolled back on the way and you can see that id is nil, created_at and updated_at are also nil in the infomation table and it can not be saved.

So this time I will explain how to save even if user_id is nil. First, open the small element model.

infomation.rb


class Infomation < ApplicationRecord
    belongs_to: user
end

I think you are forming an association like this, but please add optional: true next to it.

infomation.rb


class Infomation < ApplicationRecord
    belongs_to: user,optional: true
end

Then

Running via Spring preloader in process 6358
Loading development environment (Rails 5.2.4.4)
[1] pry(main)> Scraping.get_infomation
D, [2020-11-09T06:45:18.429070 #6358] DEBUG -- :    (0.4ms)  SET NAMES utf8,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
D, [2020-11-09T06:45:18.434125 #6358] DEBUG -- :   Infomation Load (0.2ms)  SELECT  `infomations`.* FROM `infomations` WHERE `infomations`.`name` = 'Karen Miyama' ORDER BY `infomations`.`id` ASC LIMIT 1
D, [2020-11-09T06:45:18.440170 #6358] DEBUG -- :    (0.1ms)  BEGIN
D, [2020-11-09T06:45:18.442031 #6358] DEBUG -- :   Infomation Create (0.2ms)  INSERT INTO `infomations` (`age`, `name`, `image_url`, `created_at`, `updated_at`) VALUES (23, 'Karen Miyama', 'https://images.talent-dictionary.com/uploads/images/tldb/086a19d1703dda4390ae74328861c5c858939acb.jpg', '2020-11-09 06:45:18', '2020-11-09 06:45:18')
D, [2020-11-09T06:45:18.444995 #6358] DEBUG -- :    (2.3ms)  COMMIT
Return value is: nil

[23, 32] in /home/ec2-user/environment/filebook/app/models/scraping.rb
   23:         ages = aaas.at('.age').inner_text.delete('age').to_i if aaas.at('.age')
   24:         names = aaas.at('h1').inner_text  if aaas.at('h1')
   25:         image_urls = personal_page.at('.main_image img').get_attribute('src') if personal_page.at('.main_image img')
   26:         infomation = Infomation.where(name: names).first_or_initialize
   27:         infomation.age = ages
   28:         infomation.image_url = image_urls
   29:         infomation.save
   30:         byebug
=> 31:     end
   32: end
(byebug) 

It's committed and saved !!!!!! By the way, optional: true means to allow the foreign key nil.

Recommended Posts

How foreign keys can be saved even with nil
Introduction to Java that can be understood even with Krillin (Part 1)
How to delete data with foreign key
How much IDEA can help us with Java-Spock
Organize methods that can be used with StringUtils
[Ruby] Methods that can be used with strings