今回はコンソールで動かした時にrollbackされる現象についての解決法をまとめました。
今回はスクレイピングを例に用いて説明します。 後半に解説が乗っています。
class Scraping < ApplicationRecord
def self.get_infomation
require 'mechanize'
agent = Mechanize.new
links = []
current_page = agent.get("https://talent-dictionary.com/s/jobs/3/20")
elements = current_page.at('.home_talent_list_wrapper')
boxs = elements.search('.item')
roks = boxs.search('.right')
qqqs = roks.search('a')
eees = qqqs.search('.title')
eees.each do |eee|
links << eee.inner_text
end
links.each do |link|
get_personal_infomation('https://talent-dictionary.com/' + link)
end
end
def self.get_personal_infomation(link)
agent = Mechanize.new
personal_page = agent.get(link)
aaas = personal_page.at('.talent_name_wrapper')
ages = aaas.at('.age').inner_text.delete('歳').to_i if aaas.at('.age')
names = aaas.at('h1').inner_text if aaas.at('h1')
image_urls = personal_page.at('.main_image img').get_attribute('src') if personal_page.at('.main_image img')
infomation = Infomation.where(name: names).first_or_initialize
infomation.age = ages
infomation.image_url = image_urls
infomation.save
byebug
end
end
コンソールでget_infomationを実行します。
※byebugはデバックツールです。詳しくは僕の記事を見てください。
[1] pry(main)> Scraping.get_infomation
(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
Infomation Load (0.2ms) SELECT `infomations`.* FROM `infomations` WHERE `infomations`.`name` = '広瀬すず' ORDER BY `infomations`.`id` ASC LIMIT 1
(0.1ms) BEGIN
(0.1ms) ROLLBACK
Return value is: nil
[23, 32] in /home/ec2-user/environment/filebook/app/models/scraping.rb
23: ages = aaas.at('.age').inner_text.delete('歳').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)
この結果を見る限りなぜrollbackがされているかわかりません。
このrollbackの理由を吐いてくれるコマンドがあります!!!
これは2段階あります。
一段街目は
require_relative 'boot'
require 'rails/all'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module Filebook
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 5.2
config.logger = Logger.new(STDOUT)←この列の記述
# Settings in config/environments/* take precedence over those specified here.
# Application configuration can go into files in config/initializers
# -- all .rb files in that directory are automatically loaded after loading
# the framework and any gems in your application.
end
end
2段階目
class Scraping < ApplicationRecord
def self.get_infomation
require 'mechanize'
agent = Mechanize.new
links = []
current_page = agent.get("https://talent-dictionary.com/s/jobs/3/20")
elements = current_page.at('.home_talent_list_wrapper')
boxs = elements.search('.item')
roks = boxs.search('.right')
qqqs = roks.search('a')
eees = qqqs.search('.title')
eees.each do |eee|
links << eee.inner_text
end
links.each do |link|
get_personal_infomation('https://talent-dictionary.com/' + link)
end
end
def self.get_personal_infomation(link)
agent = Mechanize.new
personal_page = agent.get(link)
aaas = personal_page.at('.talent_name_wrapper')
ages = aaas.at('.age').inner_text.delete('歳').to_i if aaas.at('.age')
names = aaas.at('h1').inner_text if aaas.at('h1')
image_urls = personal_page.at('.main_image img').get_attribute('src') if personal_page.at('.main_image img')
infomation = Infomation.where(name: names).first_or_initialize
infomation.age = ages
infomation.image_url = image_urls
infomation.save
logger.debug infomation.errors.inspect←この記述
byebug
end
end
この二つの工程を挟むと
[1] pry(main)> Scraping.get_infomation
D, [2020-11-02T13:39:29.459445 #5812] 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-02T13:39:29.464122 #5812] DEBUG -- : Infomation Load (0.2ms) SELECT `infomations`.* FROM `infomations` WHERE `infomations`.`name` = '広瀬すず' ORDER BY `infomations`.`id` ASC LIMIT 1
D, [2020-11-02T13:39:29.470351 #5812] DEBUG -- : (0.1ms) BEGIN
D, [2020-11-02T13:39:29.476168 #5812] DEBUG -- : (0.1ms) ROLLBACK
D, [2020-11-02T13:39:29.476801 #5812] DEBUG -- : #<ActiveModel::Errors:0x0000000004383ef8 @base=#<Infomation id: 14, age: 22, name: "広瀬すず", image_url: "https://images.talent-dictionary.com/uploads/image...", created_at: "2020-11-01 07:14:44", updated_at: "2020-11-01 07:14:44">, @messages={:user=>["must exist"]}, @details={:user=>[{:error=>:blank}]}>
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: logger.debug infomation.errors.inspect
31: byebug
=> 32: end
33: end
(byebug)
<ActiveModel::Errors:0x0000000004383ef8 @base=#<Infomation id: 14, age: 22, name: "広瀬すず", image_url: "https://images.talent-dictionary.com/uploads/image...", created_at: "2020-11-01 07:14:44", updated_at: "2020-11-01 07:14:44">, @messages={:user=>["must exist"]}, @details={:user=>[{:error=>:blank}]}>
このようなエラーを吐き出しました。
このエラーは訳すと{:user=>["must exist"] userが必要 しかし{:user=>[{:error=>:blank}]
でもuserのカラムが空だよと訳せます.
用はアソシエーションのエラーでのようです。
後半
loggerとはコントローラー、モデル、ビューなどのからログ(どのような処理をしたかを表すもの)を吐いてくれます。
loggerの機能はActiveSupportクラスを継承したLoggerクラスによって構成されています。
・config/application.rb
・config/evironments/xxxxxxx.rb
・ActiveSupportを継承しているクラスがあるファイルで
使うことができます。
Logger.new('ファイル名')と書くことでログの保存をするファイルを指定できます。
(STDOUT)は標準設定で'log/development.log'のファイルに保存されます
ここまでが1段階です。
二段回目は処理をするファイルの中にコードを書いていきます.
logger.debug xxxxx.errors.inspect
errors.inspectと書くとエラーを検査してくれます。
是非皆さんも実践してみてください。