gem install pgしてNo pg_configエラー

まず原因の切り分け。
確認事項

1-postgresはインストールされているか?

2-pathは通っているか?

インストールは次で確認。バージョンが表示されればインストールされているということ。
たまに起動していないこともあるので、そこもチェック

$ psql --version
psql (PostgreSQL) 9.2.24

インストールはされているらしい。

pg_configへのパスを通さないといけない。

よってpg_configファイルを探す。そこがパスと思って良い。

find /usr -name pg_config | grep pg_config

findは検索コマンド
/usrはそれ以下の場所を探すの意味
-name pg_config 名前はpg_configでね。
grepは件察結果の中から pg_configだけを表示してくださいの意味。
パイプ | 縦棒 で区切ります。

パスを追加する

~/.bash_profile にパスがまとめて書いてある

$ vim ~/.bash_profile

PATH=$PATH:/usr/lib64/pgsql92/bin          <-- コレ追加!!

次に、追加したパスをシステムに反映させるコマンド
ウインドウズのF5キーのようなもの

$ source ~/.bash_profile

パスが追加されているか確認

$echo $PATH

追加されていればOK

これで持ってbundle installを実行 すると

An error occurred while installing pg (1.1.3), and Bundler cannot continue.
Make sure that `gem install pg -v '1.1.3'` succeeds before bundling.

大丈夫。先程はpathが通っていなかったので、言われたとおりにやってもだめだった。 今度は違うはず。

gem install pg -v '1.1.3'

Building native extensions.  This could take a while...
Successfully installed pg-1.1.3
Parsing documentation for pg-1.1.3
Installing ri documentation for pg-1.1.3
Done installing documentation for pg after 1 seconds
1 gem installed

成功!

Railはバージョンをしっかり固定しないと、いけない。
最新をインストールするとするとエラーになる。
現時点で成功したgem一覧を記載しておきます。
ほぼ、デプロイ用にポスグレを入れただけのもの。
2018.9

source 'https://rubygems.org'

git_source(:github) do |repo_name|
  repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
  "https://github.com/#{repo_name}.git"
end


# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.1.6'
# Use sqlite3 as the database for Active Record
gem 'sqlite3',group: [:development,:test]
# Use Puma as the app server
gem 'puma', '~> 3.7'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby

# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.2'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.5'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '~> 2.13'
  gem 'selenium-webdriver'
end

group :development do
  # Access an IRB console on exception pages or by using <%= console %> anywhere in the code.
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '>= 3.0.5', '< 3.2'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

gem 'bootstrap-sass', '3.3.1'

gem 'sprockets'

gem 'devise'

gem "jquery-rails"

gem 'faker'
#add 2018.7.26
gem 'pry', '~> 0.11.3'

gem 'will_paginate', '3.1.6'
gem 'will_paginate-bootstrap', '1.0.1'

group :production do
 gem 'pg'
 gem 'rails_12factor'
end

Rails 検索機能実装

View側

<%= form_tag('/shops', method: 'get') do %>
<%= label_tag(:name_key, ''search name:') %>
<%= text_field_tag(:name_key) %>
<%= submit_tag('Search' %> <%= link_to 'Clear', shops_path %>
<% end %>

form_tagはフォームの開始・終了タグを生成するメソッド

第一引数には、モデルオブジェクトを記載する。
あとはオプション
検索して表示するだけだからHTTPメソッドはget

controller側

def index

  if params[:name_key]

      @shops = Shop.where('name LIKE ?',"%#{params[:name_key]}

  else

  @shops = Shop.all

  end

end

text_field_tagで:name_keyを取得していた。

それがparamsでコントローラーに渡ってくる。

それでもって検索している。

具体的にはSopモデルの中からwhere文を利用している

LIKEは含んでいる文字列を検索するメソッド、第二引数に入力値を渡している。

それだけ。

参照サイト
Paizaは結構良い

Rails入門2: 実用的なRailsサービスを作ろう「Googleマップを組み込む」 | プログラミング学習なら【paizaラーニング】

rails f.select について

<%= form_for(cat) do |f| %>
 <%= f.label :feed_id %>
    <%= f.select :feed_id, Feed.all.map{|i| [i.name, i.id] } %>

Paizaの動画教材の中
このように記載すると、なぜ下記のように表示されるのか? f:id:happy_teeth_ago:20180910115526p:plain:w300 mapで要素を2つ渡しているだけに見える。
まず前提知識としてHTMLのselect

<form action="cgi-bin/formmail.cgi" method="post">
<p>血液型:<br>
<select name="blood">
<option value="A">A型</option>
<option value="B">B型</option>
<option value="O">O型</option>
<option value="AB">AB型</option>

f:id:happy_teeth_ago:20180910115850p:plain:w300

参照サイト

<SELECT>-HTMLタグリファレンス

HTMLでは、selectの中身がoptionで表示される。

このように記載すると

<%= f.select :name, [["Railsの基礎", "rails_base"], ["Rubyの基礎", "ruby_base"]] %>

このようなHTMLが出力される
表示されるものと,valueのセットで渡すようだ

<select id="page_name" name="page[name]">
<option value="rails_base">Railsの基礎</option> 
<option value="ruby_base">Rubyの基礎</option>
</select>

railsのルール

name属性はそのままparamsのキー(シンボル)になる。

<form ...>
  <input type="text" name="text1" />
  <input type="submit" name="btnPost" value="投稿する">
</form>

これをViewからPostすると,paramsの中身はこうなります。

{
  :text1 => "入力された内容",
  :btnPost => "投稿する"
}

Rails Google Map 2回め表示しないエラー

Railsにて2回めにGoogleMAPを表示しなくなるエラーがでた。

onlodadで呼ぶだけで解決。

f:id:happy_teeth_ago:20180906132603p:plain

普通はこのように記載する。

window.onload = function() {
       initMap();
}

しかし、onloadは、最後に代入された関数が上書きされて実行される。

調査した結果、JQueryとAPIで2回呼ばれていた。 そこで、addEventListenerを利用。 これだと複数回呼ばれても、問題ない。

 
      window.addEventListener('load', function() {
       initMap();
      });

    function initMap() {
        
        var map = new google.maps.Map(document.getElementById('map'), {
          zoom: 10,
          center: {lat: <%= @user.lat %> , lng: <%= @user.lng %>}
        });
        
        var myLatLng = {lat: <%= @user.lat %> , lng: <%= @user.lng %>};
        marker = new google.maps.Marker({
          position: myLatLng
        }); 
        
        marker.setMap(map);
        markers = [] 
        markers.push(marker)

        var geocoder = new google.maps.Geocoder();

        document.getElementById('submit').addEventListener('click', function() {
          geocodeAddress(geocoder, map);
        });
      };

onloadは、DOMのレンダリングや、画像などの関連リソースが全て読み込まれてから実行される。

GoogleMAP APIは、読み込んだ時点で、intMap関数が呼ばれる。

そのために、呼び出しのタイミングが多少おかしくなっていたと思われる。

cloud9 mysql インストール手順

Cloud9にMysqlをインストールしたときにハマったので、まとめておく。 まずDBにはユーザーと権限というものを作成しないといけない。 普通のアプリケーションとは、違います。 なぜならDBはサーバーにインストールされて、そこにログインして利用します。 当然、ユーザーとパスワードが必要です。 Railsで同じサーバーで利用するときでも、DBの設計がその様になっていますので、 まずDBのユーザーを作成し、それに権限を付与します。

その上で、

フィッシャー - イェーツのシャッフルをわかりやすく説明してみた

クイズの問題

こちらを参照しました。 https://dotinstall.com/lessons/quiz_js/44207

ドットインストールはいつもわかりやすい。 勉強にはもってこいのサイト。

  var quizSet = [
    {q: 'What is A?', a: ['A0', 'A1', 'A2']},
    {q: 'What is B?', a: ['B0', 'B1', 'B2']},
    {q: 'What is C?', a: ['C0', 'C1', 'C2']}
  ];

  var currentNum = 0;



  function shuffle(arr) {
    var i;
    var j;
    var tmp;
    for (i = arr.length - 1; i >= 0; i--) {
      j = Math.floor(Math.random() * (i + 1));
      tmp = arr[i];
      arr[i] = arr[j];
      arr[j] = tmp;
    }
    return arr;
  }

  question.textContent = quizSet[currentNum].q;
  shuffledAnswers = shuffle(quizSet[currentNum].a);
  answers[0].textContent = shuffledAnswers[0];
  answers[1].textContent = shuffledAnswers[1];
  answers[2].textContent = shuffledAnswers[2];
})();
var quizSet = [
    {q: 'What is A?', a: ['A0', 'A1', 'A2']},

は回答と質問の配列。
配列の中にハッシュが入っている。
キーと値でデータを持っている。

{q: 'What is A?', a: ['A0', 'A1', 'A2']},

これだとキーがqで、 値が'What is A?'これがつまり質問
qというキーでアクセスすると、'What is A?'が取得できる。

quizSet[0].q;

でquizSetの配列の初めの要素のqつまり'What is A?'が取得できる
もう一つはいっている。それが回答
aがキー、 ['A0', 'A1', 'A2']が回答。
aのキーでアクセスすると、回答の配列が取得できる。

quizSet[0].a;

で回答の配列が取得できます。

でここからがシャッフル。 これが結構わかりにくい

//引数には配列を渡すみたい
 function shuffle(arr) {
    var i;
    var j;
    var tmp;
    for (i = arr.length - 1; i >= 0; i--) {
//乱数発生 →説明1
      j = Math.floor(Math.random() * (i + 1));
      tmp = arr[i];
      arr[i] = arr[j];
      arr[j] = tmp;
    }
    return arr;
  }

j = Math.floor(Math.random() * (i + 1));

範囲 乱数 配列      結果

1-8  6  1 2 3 4 5 8 7   6

1-8の間で乱数を発生 発生した乱数を取り出す
それを配列arr配列の中で置き換えている。
配列の一番最後に入れている。
二回目のループではこうなる

範囲 乱数 配列      結果(配列の最後に配置)

1-7  2  1 3 4 5 8 7   2 6

これを繰り返すと、配列の中がシャッフルされる。

Ruby injectについて

よくある説明
injectメソッドは、ブロックを使って繰り返し計算を行うのに使います。ブロックに順に「要素1、要素2」、「ブロックの前回の戻り値、要素3」、「ブロックの前回の戻り値、要素4」、...を渡します。メソッドの戻り値はブロックが最後に返した値になります。

numbers = [4, 3, 9, 8, 5, 6, 1, 7, 2]
puts numbers.inject {|sum, n| sum + n }

=>45

これでは、初学者にはわからないと思います。
それでわかりやすくまとめてみます。
つまるところ
(((((((4+3)+9)+)8)+)5)+)6)+)1)+)7)+2) をやっています。

ブロックの引数 => | ブロック引数 |  sum,とnには初め、要素の1番めと2番めの4と3が入ります

4+3 が実行され 7になります。    そして結果の7が次のループで、ブロック引数の1つ目のsumに代入されて、次の要素9が回ります。

よって2回めはのループでは、7+9 が実行され18になります。

3回めはsum に18が入り 18+8 が実行され 26になります。 これが次のループのときのsumに入ります。
畳み込み演算と呼ばれたりもします。
swiftにも同じ様なものがあります。