0
1

More than 3 years have passed since last update.

Ruby on Rails terminalがrollbackする時

Posted at

今回はコンソールで動かした時にrollbackされる現象についての解決法をまとめました。
今回はスクレイピングを例に用いて説明します。 後半に解説が乗っています。

scraping.rb
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段階あります。
一段街目は

aplication.rb


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段階目

scraping.rb
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と書くとエラーを検査してくれます。

是非皆さんも実践してみてください。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1