u16suzuの blog

日々学んだことのメモブログです。

ARの自己結合と関連をcreate

自己結合

自己テーブルを参照する関連も作ることができる

class AddColumnToPosts < ActiveRecord::Migration[6.0]
  def change
    add_reference :posts, :prev_post
    add_reference :posts, :next_post
  end
end
class Post < ApplicationRecord
  belongs_to :category

  has_many :prev_posts, class_name: "Post", foreign_key: "prev_post_id"
  belongs_to :next_post, class_name: "Post"
end

以下のメソッドが使えるようになる.

> Post.last.next_post
> Post.last.prev_posts

関連をcreate

# これだけでcommitされる
Category.last.posts.create( title: "a", body: "bb")

ARのrelationのメソッド定義

Association extensions

# Post::ActiveRecord_Associations_CollectionProxy に hoge メソッドを生やす.
# 当然メソッド内でのselfはPst::ActiveRecord_Associations_CollectionProxyで posts が入っている。
# CollectionProxyに生えているので 当然 Post.first.hoge ではよべない.
# posts.hoge でだけcall可能
# 引数で値を取れる。自分の値は取れないらしい。  
has_many :posts do
  def hoge(title)
    p title
    p self.class
  end
end

Extending

module を使って共通化できる

module Foo
  def foo_method
  end
end

class Category < ApplicationRecord
  has_many :foo, -> { extending Foo }, class_name: "Post", foreign_key: "category_id"
end

.pryrc

# encoding: utf-8
# require "~/.pry/bokudora.rb"


### エイリアス
Pry.commands.alias_command 'c', 'continue'
Pry.commands.alias_command 'n', 'next'
Pry.commands.alias_command 's', 'step'
Pry.commands.alias_command 'f', 'finish'

Pry.commands.alias_command 'e', 'edit'    # open with rubymine
Pry.commands.alias_command 'mi', 'edit'   # open with rubymine
Pry.commands.alias_command 'mine', 'edit' # open with rubymine
# gem 'pry-stack_explorer'
Pry.commands.alias_command 'ss', 'show-stack'
Pry.commands.alias_command 'code', 'show-source'


# Hit Enter to repeat last command
Pry::Commands.command /^$/, "repeat last command" do
  command = Pry.history.to_a.last

  _pry_.run_command(command) unless command == "exit" # 起動直後にenter押下で即終了するのを防ぐ
end


Pry.config.editor = proc { |file, line| "/usr/local/bin/mine --line #{line} #{file}" }
Pry.config.pager  = true


# プロンプト
Pry.config.prompt = proc do |obj, nest_level, _pry_|
  prompt = ""
  prompt << "#{Pry.config.prompt_name.to_s.blue}"
  prompt << "(#{Pry.view_clip(obj).to_s.cyan})"
  prompt << "[#{RUBY_VERSION.to_s.green}]"
  prompt << "> "
end


# 外部gemのコードを省いた call stack
def caller_products
  caller.reject {|l| l.include?( 'gems' )}
end

# 外部gemのコードのみの call stack
def caller_gems
  caller.select {|l| l.include?( 'gems' )}
end

class String
  def red;    "\e[31m#{self}\e[0m"; end
  def green;  "\e[32m#{self}\e[0m"; end
  def yellow; "\e[33m#{self}\e[0m"; end
  def blue;   "\e[34m#{self}\e[0m"; end
  def magenta;"\e[35m#{self}\e[0m"; end
  def cyan;   "\e[36m#{self}\e[0m"; end
  def bold;   "\e[1m#{self}\e[0m"; end
  def back_blue;   "\e[44m#{self}\e[0m"; end
end

Railsで使っているgemの内部で実行を止める

以下をコードの止めたいところに書けば良い。 メソッドの定義内に書いても問題ない。

require "pry"; binding.pry

コードを確認し終わって、元に戻したい時は以下を実行すれば良い。

$ bundle pristine GEM_NAME

so that 構文の4種類の用法

当時、筆者が中学で習った so that 構文は「とても~なので…です」 と1種類だけなので容易に覚えることができました。 しかしながら、仕事で英語に触れる機会が増えてくると、上と似たような so that が出てくる文章ではあるけれども、上の意味で訳すとどうも意味が通らないケースが多いのです。 そこでよくよく調べてみますと、 so that 構文には4種類の用法がありました。

1. 程度・結果(~するほど...だ、とても...なので~だ)

so の後に 形容詞か副詞 がきます。

まずは中学英語で習った so that 構文ですね。

He is so hungry, that he can eat anything.
(彼はなんでも食べられる程空腹だ。)

too~ to... (あまりに~すぎて、... できない) と書き換えさせる問題がよく出題されました。

2. 様態(~するように...)

so の後に 過去分詞 がきます。

This bicycle is so made that it drives speedy.
(この自転車は早く走れるように作られている。)

様態とは聞き慣れない言葉ですが、「物事のありかた。様相」という意味です。

3. 目的(~するために...)

so と that がくっついています。

後節が目的を示す節となっています。

I work so that I earn money for tuition of university.
(私は大学の学費を稼ぐために働いている。)

The Architecture of Open Source Applications (Volume 2): nginx の 14.4. nginx Internals を読んでいて見つけたので訳してみます。

For a directory it would automatically rewrite the URI so that the trailing slash is always there (and then issue an HTTP redirect).
(ディレクトリの場合は、trailing slash を付加するために自動的でURIに変換されます。その後、HTTP リダイレクトが行われます。)

4. 結果(~その結果...)

  1. のパターンに加えてカンマが先頭につきます。
I study hardly, so that I passed the difficult examination. 
(ハードに勉強した。その結果、難しい試験をパスした。)

省略について

so that 構文では、口語では that が, 文語では so が省略されることがよくあるようです。

  • 口語

I study hardly, so I passed the difficult examination.

  • 文語

I study hardly, that I passed the difficult examination.

うーん。口語の方はわかるんですが、文語の方はこの事をわかってないと、なかなか意味を取るのは難しそうですね。 初期に習う単語ほど、色々な語法が多くて混乱の要因になることが多い気がします。

参考にした記事

こちらの記事を参考にさせていただきました。ありがとうございます!

Rubyでグラフを表現してみる

class Vertex
  attr_accessor :id, :edges
  def initialize(id, edges=[])
    @id = id
    @edges = edges
  end

  def print
    puts "#{ @id }"

    @edges.each do |edge|
      puts edge
    end
  end
end

class Edge
  attr_accessor :id, :from, :to, :length
  def initialize(id, from, to, length)
    @id = id
    @from = from
    @to = to
    @length = length
  end

  def to_s
    "#{ from } => #{ to } #{ length }"
  end
end

class Graph
  attr_accessor :vertexes, :edges
  def initialize(data)
    @vertexes = []
    data.each do |k, v|

      edges = []
      v.each do |k2, v2|
        edges << Edge.new( 0, k ,k2, v2 )
      end

      @vertexes << Vertex.new( k, edges )
    end
  end

  def print_graph
    @vertexes.each do |v|
      v.print
    end
  end
end

data =
    {
        a: {b: 1, c: 3, d: 4},
        b: {b: 3, d: 11},
        c: {a: 1},
        d: {e: 11},
        e: {a: 1},
    }


g = Graph.new( data )
g.print_graph

実行結果

a
a => b 1
a => c 3
a => d 4
b
b => b 3
b => d 11
c
c => a 1
d
d => e 11
e
e => a 1