rails db:migrate:status に "******no file ********"がある時

title通り

rails db:migrate:status に "no file **"がある時 の対処について考えてみます。

すでに本項目の対処記事というものは上がっておりますが 僕の環境では一箇所詰まってので改めて記事にしています。

そもそも絵タイトルの状態 is 何?という人は rails アプリケーションディレクトリにて rails db:migrate:status もしくは rake db:migrate:status と実行してみてください。 過去に.....pending migrations error.....とかをみていたりすると このコマンドしっているんじゃないかなと思いますが、、、

下記のような結果が帰ってくると思います。 gyazo.com

それぞれが何を意味しているのか。。。 status →migrationファイルの実行状況です。upとされていれば該当migrationファイルは実行済みとなっています。  逆にdownになっていれば、そのmigrationファイルは未実行状態なのでファイル編集や削除等を気兼ねなく行えます!

migration_ID →こちらは rails g migration ~~ というコマンドを実行した際のタイムスタンプになっています! UTCを基準にスタンプしているようです。  基本的に 年月日、~時~分~ 秒という単位になっているので同じタイムスタンプがつくことはまぁ、ないでしょう

MigrationNAME →migration name というのは該当migrationファイルの名前(クラス名)です

ところで、本記事をみているということはmigrationで何かミスを犯したということですね???????

→執筆時点で私もミスをしていましたが。.......w

基本的に status が upになっているmigration ファイルの削除、及び変更は禁止 です! これはrails のmigrationの実行状態は db/schema.rbというファイルにて管理しています。 shcemaファイルというのはとても重要になっており。 migrationファイルの実行によって書き込まれ、同時にrailsmysqlsqliteといったdatabaseへtable作成、レコードの(追加|削除|など)といったSQLの発行をしています。

つまり、migrationファイルを実行した後はDBへの命令も実行がされています! その状態でmigrationファイルを削除したり、編集してしまうとmigrationファイルと,db/schema.rbの整合性がうしなわれてしまうのですorz。。。。。。。

※特にアプリケーションをデプロイする予定がある人などはmigrationファイルは綺麗に管理しておいた方が良いですね。 →上から順番にmigarationを実行する際に整合性が失われていると rake abortとなり、えらー解決をしないといけません。.......(こいつがめんどくさい)

ではno fileとなってしまったらどうしたらいいのか!

方法としては、nofileとなっているmigrationファイルをコマンド等を利用して、ファイルを作成します。 DBに対して何も命令をしないmigratioファイルを作成 そのファイルのstatus を downに変更 →うまくいったら削除。 というのが全体の流れです!

対処。

gyazo.com このnofileになっているファイルの注目すべき箇所はmigration_idです。

20171010091337 となっていますね。 本来であれば、~1010091337となっているファイルがあったはずなのに、何かの拍子に消してしまったと… (過去の大罪ですね…)

ではこのNofileとなってしまっているマイグレーションの齟齬を合わせるためのtmpファイルを作成し、DBに変更を加えないファイルを作っていたあげればよい。というのが本案件の解決策です。

cd db/migrate touch ~さっきのマイグレーションid~_tmp.rb(下記) そしてエディタ、(vim等)で編集していきます。

class Tmp < ActiveRecord::Migration[5.1]
  def change

  end
end

はい。こちらのように変更した後で

rails db:migrate:status として見ると、Nofileとなってしまっていた箇所が tmpファイルに置き換わっています!

次は、そのふぁいるをrollbackしてあげればいい。

rails db:rollback もしくは

rails db:migrate:down VERSION=[バージョン番号]

のようにしてあげれば良いのです。

正常に動作すると

rails db:migrate:status と実行すると "no file **" このmigrationファイルがdownになってると思われます それをコマンドないしfinderなどから削除してあげれば対応完了です

n番煎じのような記事になってしまいましたがfumihumiサクッとメモでした

javascriptで Document.getElementByXpath で検索したかった。

javascriptXpathで検索したかった。

普段rubyでscrapingやcrawlerをつくるなどするときはRubyGemsの'capybara,Nokogiri,Mechanize'といったものを利用しているため大抵のDocument検索はXpathをつかって検索していました。

久しぶりにJavascriptを使ってJSを書くとき。 'あの要素Xpathでとれないかなと思い'おもむろに

document.getElementByXpath()

と実行したところ

VM324:1 Uncaught TypeError: document.getElementByXpath is not a function
    at <anonymous>:1:10

そんなものないよと怒られた。

G先生にきくと下記のようなfuncを定義すれば良いとのことなのでこれを使ってあげれば JavascriptにてXpathで要素取得が可能になります。

function getElementByXpath(path) {
  return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}

-----追記

Githubで同じようなことをやっている人がいないかなと思い、検索したらまとめてる方がいました。

gist.github.com

document.getElementByXPath = function(sValue) { var a = this.evaluate(sValue, this, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); if (a.snapshotLength > 0) { return a.snapshotItem(0); } };
document.getElementsByXPath = function(sValue){ var aResult = new Array();var a = this.evaluate(sValue, this, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);for ( var i = 0 ; i < a.snapshotLength ; i++ ){aResult.push(a.snapshotItem(i));}return aResult;};
document.removeElementsByXPath = function(sValue) { var a = this.evaluate(sValue, this, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); for ( var i = 0 ; i < a.snapshotLength ; i++ ) { a.snapshotItem(i).parentNode.removeChild(a.snapshotItem(i)); } };

---追記終わり

fumihumiサクッとメモでした。

参考: stackoverflow.com

追記

chromeにはwindow.$x というものがあり、

ƒ $x(xpath, [startNode]) { [Command Line API] }

となっていました。

ブラウザで検証等を使って試す時は

$x(xpath)

で良いようです。(chrome, safariにて動作を確認しました)

web ViewでなんちゃってPWAを作ってみた。 ~javascript alert()が動かない~

PWAとは

..progressive web apps

とよばれるアプリケーションですね。詳しいことは割愛しますが。基本的には ブラウザ最強! ネイティブアプリいらなくね?????? というような思想(違う)というものです。。

ただ、iOSsafariでは、まだPWAの基盤になりうる、push通知やservice worker などがまだ実装されていないのです。

そこで今回はwebViewにしてみました。 その際のTipsを軽くまとめます。

javascript の alert関数や comfirm のウインドウが開かない

今回は該当のVC (WebViewを使っているVC) に対してWKUIDelegateを使いjavascriptがうまく動くように実装します。

extension SampleViewController: WKUIDelegate {
    
    // alertを表示する
    func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
        
        let alertController =
            UIAlertController(title: "", message: message, preferredStyle: .alert)
        
        let okAction =
            UIAlertAction(title: "OK", style: .default) { action in
                completionHandler()
        }
        
        alertController.addAction(okAction)
        present(alertController, animated: true, completion: nil)
    }
    
    // confirm dialogを表示する
    func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
        
        let alertController =
            UIAlertController(title: "", message: message, preferredStyle: .alert)
        
        let cancelAction =
            UIAlertAction(title: "Cancel", style: .cancel) { action in
                completionHandler(false)
        }
        
        let okAction =
            UIAlertAction(title: "OK", style: .default) {
                action in completionHandler(true)
        }
        
        alertController.addAction(cancelAction)
        alertController.addAction(okAction)
        
        present(alertController, animated: true, completion: nil)
    }
    
}

このようにすることで alert(), comfirm()が正常に動くようになります。

why ?

webViewは基本的にブラウザのWindowを一つしか描画しないようです。

しかしながらJavascriptを利用すると、ブラウザはalert用のwindowを新規に作成します。 つまり、本来であればブラウザの中に別のwindowを展開するのですが、webviewではそれが不可能なので、 swiftの alertViewを利用してalertを表示するようにします。

こうすることでwebViewにてjavascriptのalert, comfirmが動くようになります。

インジケータを出したい。

extension SampleViewController: WKNavigationDelegate {
    
    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        UIApplication.shared.isNetworkActivityIndicatorVisible = true
        showIndicator()
    }
    
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        UIApplication.shared.isNetworkActivityIndicatorVisible = false
        self.view = webView
        self.indicator.stopAnimating()
    }
    
}

こうすることでwebViewの中でロードしている最中はstatus bar にてインジケータが出ます。

fumihumiサクッとメモでした。

Podfileを変更したときに’Linker Error’になった。

Podfileを変更したときに’Linker Error’になった。

self.memo for 未来の自分へ

cocoapodにてライブラリ管理をしていると このらいぶらり古いやん。 変更しよ。 となることが多いと思うのですが。その際に下記のようなエラーが出たとき。

clang: error: linker command failed with exit code 1 (use -v to see invocation)

この前にも

ld: library not found

のようなエラーがある、 つまりこの後に続くlibraryが該当プロジェクトにないというエラーっぽい。

GUIでproject→General→ Linked Frameworks and Librariesのところを編集してなかったことが原因でしたとさ。。

podでインストールしたら上記を書き換える人もいるのかなと思います。それを忘れるとエラーになってしまう。

bootstrap4 flexで'wrap'されない

memo

タイトルのような環境にて開発している時に

                <div class="screen-shot d-flex flex-row flex-wrap">
                    <img src='/image/mac_screen_shot.png' class='screen-shot-mac'>
                    <img src='/image/iphone_screen_shot.png' class='screen-shot-iphone' >
                </div>

としていたら思っていた挙動になりませんでした。

これは

flex-row

flex-wrap

この相反する要素が競合していることが原因だと思います。

flex-rowを削除してやることでうまく動くことができました。

rbenv global ~~が切り替わらない。 homebrew で '/usr/local/bin/brew: line 79: /usr/bin/env: Argument list too long', '/usr/local/bin/brew: line 79: /usr/bin/env: Undefined error: 0'

結論 ~/.bash_profileにPATHを改変する記述があった。

export PATH="/usr/local/bin:$PATH"

状況

私はrubyを割と頻繁に記述をしているのですが、とあるプロダクトにて.ruby-versionを使った管理がありました、 ただ ruby -v をしても。指定のヴァージョンにはなっておらず。

@fumihumi:which ruby /usr/local/bin/ruby

ruby のパスを見ているとなぜか。 '/usr/local/bin/ruby' ............

正しくは '.rbenv'を見にいって欲しいのだが。 @fumihumi:which ruby /Users/fumihumi/.rbenv/shims/ruby

色々調べてみると ’~/bash_profile’がおかしい。というパターンでのエラーが多いらしい。 そりゃ

if [ -f ~/.bashrc ] ; then
    . ~/.bashrc
    fi
# rbenv
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"

と書いているからこれが読めれば動くよね。。という話。

まず確認したいことはコマンドで

eval "$(rbenv init -)"

として動くのか否か 基本的に環境が問題なければ

  $which ruby
      /usr/local/bin/ruby
  $eval "$(rbenv init -)"  
  $which ruby
      /Users/fumihumi/.rbenv/shims/ruby

このようにevalコマンドの後にPATHが変わります。

実際に私も変わってました。

無知な私はここで最大の過ちを犯します。

エンジニア人生のおわり\

systemのrubyを使ってるなら 削除すれば良くね? >>>>>>>>>>>>ダメです!!!1

$ brew list を見ているとインストールした記憶のない ruby がいる、殺す。

@fumihumi:brew remove  ruby
Error: Refusing to uninstall /usr/local/Cellar/ruby/2.5.0_2
because it is required by vim 8.0.1300, vim 8.0.1171, vim 8.0.1600, which are currently installed.
You can override this and force removal with:
  brew uninstall --ignore-dependencies ruby

なんか言われているけど消したいので。

brew uninstall --ignore-dependencies ruby

どーん!

と消す

消えたことを確認しよう。

brew list
/usr/local/bin/brew: line 79: /usr/bin/env: Argument list too long
/usr/local/bin/brew: line 79: /usr/bin/env: Undefined error: 0

a。? あれ??? brew が使えない?

やばい。brewが使えないとどうにもできない。。

Homebrew(https://brew.sh/index_ja)を入れ直そう!。 しかし公式のインストーラでは。'/usr/bin/ruby'を見にいっている

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

これは実行できません。 (さっき吹き飛ばしたからね!w)

ではどうするのか。

...... rbenv入ってたよな。。。。。

@fumihumi: eval "$(rbenv init -)"

@fumihumi:ruby -v
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-darwin16]

これでrubyコマンドは使える。 利用するRubyを変えればさっきのインストールがいけるはず。

@fumihumi:ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
==> This script will install:
/usr/local/bin/brew
/usr/local/share/doc/homebrew
/usr/local/share/man/man1/brew.1
/usr/local/share/zsh/site-functions/_brew
/usr/local/etc/bash_completion.d/brew
/usr/local/Homebrew
==> The following new directories will be created:
/usr/local/sbin

Press RETURN to continue or any other key to abort
==> /usr/bin/sudo /bin/mkdir -p /usr/local/sbin
Password:
==> /usr/bin/sudo /bin/chmod g+rwx /usr/local/sbin
==> /usr/bin/sudo /bin/chmod 755 /usr/local/share/zsh /usr/local/share/zsh/site-functions
==> /usr/bin/sudo /usr/sbin/chown fumihumi /usr/local/sbin
==> /usr/bin/sudo /usr/bin/chgrp admin /usr/local/sbin
==> /usr/bin/sudo /bin/mkdir -p /Library/Caches/Homebrew
==> /usr/bin/sudo /bin/chmod g+rwx /Library/Caches/Homebrew
==> /usr/bin/sudo /usr/sbin/chown fumihumi /Library/Caches/Homebrew
==> Downloading and installing Homebrew...
remote: Counting objects: 235, done.
remote: Compressing objects: 100% (60/60), done.
remote: Total 235 (delta 188), reused 210 (delta 174), pack-reused 0
Receiving objects: 100% (235/235), 44.01 KiB | 7.33 MiB/s, done.
Resolving deltas: 100% (188/188), completed with 117 local objects.
From https://github.com/Homebrew/brew
   0851f967..0f4e22e2  master     -> origin/master
HEAD is now at 0f4e22e2 Merge pull request #3981 from MikeMcQuaid/rspec-cleanup
/usr/local/bin/brew: line 79: /usr/bin/env: Argument list too long
/usr/local/bin/brew: line 79: /usr/bin/env: Undefined error: 0
Failed during: /usr/local/bin/brew update --force

あれ、うまくいってない??????

懲りずに何度かチャレンジするとうまくいきました。

めでたし。

その後。

brew が使えるようになったのですが。結局

which ruby

の結果は変わらず同じでした。 ひらすら'.bash_profile'を眺める。

結論

結論 ~/.bash_profileにPATHを改変する記述があった。

export PATH="/usr/local/bin:$PATH"

環境変数の変更コードはコピペが多いのですが、その際に持ってきたのでしょう。 この一行があるだけで rbenv init -が実行できていなかったようです。 コメントアウトしてやることで現状は打破しました。

似たような症状の人の助けになれば幸いです。

'You can't use Gon public methods for storing ~~'って怒られて悩んだ話。

railsにてcontrollerで用意した変数をjavascriptに直接渡すことができるようになる、gem gonを使っていて、表題のエラーに遭遇しました

'You can't use Gon public methods for storing ~~'

結果 

利用していた変数名が 予約語 だった。 変数名を変更したら解決しました。