Rails 基礎3

### relation(belongs:to)
$ rails g model Comment body:string post:references
$ rails db:migrate

model
app/models.comment.rb

class Comment < ApplicationRecord
  belongs_to :post
  validates :body, prensence: true
end

post modelにもcommentと紐づいていることを書く

class Post < ApplicationRecord
	has_many :comments
	validates :title, presence: true, length: {minimum: 3, message: 'too short to post!'}
	validates :body, presence: true
end

post.comments と書くことができる様になる

routes.rb

  resources :posts do
  	resources :comments
  end

$ rails routes
Prefix Verb URI Pattern Controller#Action
post_comments GET /posts/:post_id/comments(.:format) comments#index
POST /posts/:post_id/comments(.:format) comments#create
new_post_comment GET /posts/:post_id/comments/new(.:format) comments#new
edit_post_comment GET /posts/:post_id/comments/:id/edit(.:format) comments#edit
post_comment GET /posts/:post_id/comments/:id(.:format) comments#show
PATCH /posts/:post_id/comments/:id(.:format) comments#update
PUT /posts/:post_id/comments/:id(.:format) comments#update
DELETE /posts/:post_id/comments/:id(.:format) comments#destroy
posts GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post GET /posts/new(.:format) posts#new
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
PATCH /posts/:id(.:format) posts#update
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
root GET / posts#index

$ rails g controller Comments

show.html.erb

<h3>Comments</h3>
<%= form_for ([@post, @post.comments.build]) do |f| %>
<p>
	<%= f.text_field:body %>
</p>
<p>
	<%= f.submit %>
</p>
<% end %>

comments_controller.rb

	def create
		# render plain: params[:post].inspect
		@post = Post.find(params[:post_id])
		@post.comments.create(comment_params)
		redirect_to post_path(@post)
	end

	private
		def comment_params
			params.require(:comment).permit(:body)
		end

posts_controller.rb
L 変更なし

	def show
		@post = Post.find(params[:id])
	end

show.html.erb

<ul>
	<% @post.comments.each do |comment| %>
	<li>
		<%= comment.body %>
		<%= link_to '[x]', 
			post_comment_path(@post, comment), 
			method: :delete, 
			class: 'command',
			data: { confirm: 'Sure ?'} %>		
	</li>
	<% end %>
</ul>

controller

	def destroy
		@post = Post.find(params[:post_id])
		@comment = @post.comments.find(params[:id])
		@comment.destroy
		redirect_to post_path(@post)
	end

route

Rails.application.routes.draw do
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
  resources :posts do
  	resources :comments, only: [:create, :destroy]
  end

  root 'posts#index'
end

記事を削除した時にコメントも削除する
model

class Post < ApplicationRecord
	has_many :comments, dependent: :destroy
	validates :title, presence: true, length: {minimum: 3, message: 'too short to post!'}
	validates :body, presence: true
end

なるほど、オリジナルで作らんとダメやな

Rails 基礎2

viewでヘルパーを使用
index.html.erb

		<% @posts.each do |post| %>
		<li>
			<%= link_to post.title, post_path(post) %>				
		</li>
		<% end %>

posts_controller.rb

	def show
		@post = Post.find(params[:id])
	end

show.html.erb

<h2><%= @post.title %></h2>
<p><%= @post.body %></p>

app/assets/images/logo.png
link_toでリンクを指定し、root_pathでリンク先を指定する

  	<div class="container">
  		<h1><%= link_to image_tag('logo.png', class: 'logo'), root_path %></h1>
    <%= yield %>
	</div>

css

.logo {
	width: 200px;
	height: 50px;
}

リンクを作成する

	<h2>
		<%= link_to 'Add New', new_post_path, class: 'header-menu' %>
		My Posts
	</h2>

css

.header-menu {
	font-size: 12px;
	font-weight: normal;
	float: right;
}

controller

	def new
	end

	def create
	end

new.html.erb

<h2>Add New Post</h2>
<%= form_for :post, url:posts_path do |f| %>
<p>
	<%= f.text_field:title, placeholder: 'enter title' %>
</p>
<p>
	<%= f.text_area:body, placeholder: 'enter body text' %>
</p>
<p>
	<%= f.submit %>
</p>
<% end %>

css

input[type="text"], textarea {
	box-sizing: border-box;
	width: 400px;
	padding: 5px;
}

textarea {
	height: 160px;
}

posts_controller.rb

	def create
		render plain: params[:post].inspect
	end

“aa”, “body”=>”bb”} permitted: false>

	def create
		# render plain: params[:post].inspect
		@post = Post.new(params[:post])
		@post.save
		redirect_to posts_path
	end

private methodで書く

	def create
		# render plain: params[:post].inspect
		@post = Post.new(post_params)
		@post.save
		redirect_to posts_path
	end

	private
		def post_params
			params.require(:post).permit(:title, :body)
		end

バリデーション
app/models/post.rb

class Post < ApplicationRecord
	validates :title, presence: true, length: {minimum: 3, message: 'too short to post!'}
	validates :body, presence: true
end

controller

	def create
		# render plain: params[:post].inspect
		@post = Post.new(post_params)
		if @post.save
			redirect_to posts_path
		else
			render 'new'
		end
	end

view

<p>
	<%= f.text_field:title, placeholder: 'enter title' %>
	<% if @post.errors.messages[:title].any? %>
	<span class="error"><%= @post.errors.messages[:title][0] %></span>
	<% end %>
</p>
<p>
	<%= f.text_area:body, placeholder: 'enter body text' %>
	<% if @post.errors.messages[:body].any? %>
	<span class="error"><%= @post.errors.messages[:body][0] %></span>
	<% end %>
</p>

### edit
index.html.erb

			<%= link_to post.title, post_path(post) %>	
			<%= link_to '[Edit]', edit_post_path(post), class: 'command' %>		

controller

	def edit 
		@post = Post.find(params[:id])
	end

edit.html.erb
L newとほぼ同じ

<h2>Edit Post</h2>
<%= form_for @post, url:post_path(@post) do |f| %>
<p>
	<%= f.text_field:title, placeholder: 'enter title' %>
	<% if @post.errors.messages[:title].any? %>
	<span class="error"><%= @post.errors.messages[:title][0] %></span>
	<% end %>
</p>
<p>
	<%= f.text_area:body, placeholder: 'enter body text' %>
	<% if @post.errors.messages[:body].any? %>
	<span class="error"><%= @post.errors.messages[:body][0] %></span>
	<% end %>
</p>
<p>
	<%= f.submit %>
</p>
<% end %>

controller

	def update
		@post = Post.find(params[:id])
		if @post.update(post_params)
			redirect_to posts_path
		else
			render 'edit'
		end
	end

改行を適切なタグに直す

<h2><%= @post.title %></h2>
<p><%= simple_format @post.body %></p>

### partialで共通部品を作る
partialはアンダーバー(_)から始める
views/posts/_form.html.erb

<%= form_for @post do |f| %>
<p>
	<%= f.text_field:title, placeholder: 'enter title' %>
	<% if @post.errors.messages[:title].any? %>
	<span class="error"><%= @post.errors.messages[:title][0] %></span>
	<% end %>
</p>
<p>
	<%= f.text_area:body, placeholder: 'enter body text' %>
	<% if @post.errors.messages[:body].any? %>
	<span class="error"><%= @post.errors.messages[:body][0] %></span>
	<% end %>
</p>
<p>
	<%= f.submit %>
</p>
<% end %>

edit.html.erb
L partialの名前をアンダーバー抜きで書く

<h2>Edit Post</h2>
<%= render 'form' %>

new.html.erb

<h2>Add New Post</h2>
<%= render 'form' %>

### delete

		<li>
			<%= link_to post.title, post_path(post) %>	
			<%= link_to '[Edit]', edit_post_path(post), class: 'command' %>
			<%= link_to '[x]', 
			post_path(post), 
			method: :delete, 
			class: 'command',
			data: { confirm: 'Sure ?'} %>	
		</li>

controller

	def destroy
		@post = Post.find(params[:id])
		@post.destroy
		redirect_to posts_path
	end

Rails 基礎1

– model作成
$ rails g model Post title:string body:text
$ rails db:migrate

### DB接続
$ rails db
sqlite> .tables
ar_internal_metadata posts schema_migrations
// テーブル名は複数形になる
sqlite> select * from posts;
1|title1|body1|2022-01-03 00:47:27.389516|2022-01-03 00:47:27.389516
2|title2|body2|2022-01-03 00:47:34.246581|2022-01-03 00:47:34.246581
sqlite> .quit

db/seeds.rb に初期データを書ける

5.times do |i|
	Post.create(title: "title #{i}", body: "body #{i}")
end

テーブルの中身をリセット
$ rails db:migrate:reset
$ rails db:seed
sqlite> select * from posts;
1|title 0|body 0|2022-01-03 02:38:34.229316|2022-01-03 02:38:34.229316
2|title 1|body 1|2022-01-03 02:38:34.242102|2022-01-03 02:38:34.242102
3|title 2|body 2|2022-01-03 02:38:34.248025|2022-01-03 02:38:34.248025
4|title 3|body 3|2022-01-03 02:38:34.253382|2022-01-03 02:38:34.253382
5|title 4|body 4|2022-01-03 02:38:34.259377|2022-01-03 02:38:34.259377

### controller
$ rails g controller Posts

config/routes.rb

Rails.application.routes.draw do

  resources :posts
end

$ rails routes
Prefix Verb URI Pattern Controller#Action
posts GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post GET /posts/new(.:format) posts#new
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
PATCH /posts/:id(.:format) posts#update
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy

app/controllers/post_controller.rb

class PostsController < ApplicationController

	def index
		@posts = Post.all.order(created_at: 'desc')
	end
end

app/views/posts/index.html.erb

	<h2>My Posts</h2>
	<ul>
		<% @posts.each do |post| %>
		<li><%= post.title %></li>
		<% end %>
	</ul>

$ rails s -b 192.168.33.10 -d
http://192.168.33.10:3000/posts

route pass

Rails.application.routes.draw do
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
  resources :posts

  root 'posts#index'
end

app/views/layouts/application.html.erb
app/assets/stylesheets/application.css

.container {
	width: 400px;
	margin: 20px auto;
}
body {
	font-family: Verdana, sans-serif;
	font-size: 14px;
}
h2 {
	font-size: 16px;
	padding-bottom: 10px;
	margin-bottom: 15px;
	border-bottom: 1px solid #ddd;
}

ul > li {
	margin-bottom: 5px;
}

ubuntu20.04でRailsを触りたい

### 環境構築
$ ruby -v
$ rbenv install –list
$ rbenv install 2.7.2

$ sudo apt install sqlite3
$ sqlite3 –version
3.31.1 2020-01-27 19:55:54 3bfa9cc97da10598521b342961df8f5f68c7388fa117345eeb516eaa837balt1

$ gem install rails -v 5.1.3 –no-document
$ sudo apt install ruby-railties
$ rails -v
Rails 5.1.3

### railsアプリ
$ rails new myapp
$ rails server -b 192.168.33.10 -d
=> Booting Puma
=> Rails 5.1.7 application starting in development
=> Run `rails server -h` for more startup options

サーバーのdown
$ cat tmp/pids/server.pid
24555
$ kill -9 24555

ログ
$ tail log/development.log

### scaffold
$ rails g scaffold Memo title:string body:text
$ rails db:migrate

http://192.168.33.10:3000/memos

$ ps aux | grep puma
$ kill -9 24777

app, config, dbなどを主に使用する

### model作成
単数系になる
$ rails g model Post title:string body:text
$ rails db:migrate

### データ挿入
$ rails c

$ p = Post.new(title:’title1′, body:’body1′)
$ p.save

$ Post.create(title:’title2′, body:’body2′)

$ Post.all
$ quit

ruby install

$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
$ echo ‘export PATH=”$HOME/.rbenv/bin:$PATH”‘ >> ~/.bash_profile
$ echo ‘eval “$(rbenv init -)”‘ >> ~/.bash_profile
$ source ~/.bash_profile

$ rbenv install –list
$ rbenv install 2.7.0
$ rbenv global 2.7.0
$ rbenv rehash

$ which ruby
$ ruby –version

$ sudo yum install rubygems
$ gem update –system 2.7.10

ECDSA

ECDSA(Elliptic Curve Digital Signature Algorithm)
楕円曲線デジタル署名アルゴリズム
ビットコインの電子証明などに利用されている
ECDSAは公開鍵の暗号化技術の名前
RSAに比べ約1/10のコンパクトな容量

require 'ecdsa'
require 'securerandom'

group = ECDSA::Group::Secp256k1
n = group.order

private_key = 1 + SecureRandom.random_number(n-1)

print private_key

vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ ruby main.rb
106515493506888278075922016172190811663525618981292515102301206639235796458599

ビットコインの暗号技術

OpenSSL
-> インターネット上で標準的に利用される暗号通信プロトコルであるSSLおよびTLSの機能を実装したオープンソースライブラリ

require 'openssl'

data = '*secret data*'

key = 'a' * 32
iv = 'i' * 16

enc = OpenSSL::Cipher.new('AES-256-CBC')
enc.encrypt
enc.key = key
enc.iv = iv
encrypted_data = enc.update(data) + enc.final
# print encrypted_data

dec = OpenSSL::Cipher.new('AES-256-CBC')
dec.decrypt
dec.key = key
dec.iv = iv 
decrypted_data = dec.update(encrypted_data) + dec.final
print decrypted_data

vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ ruby main.rb
5????
g`??Ա?

vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ ruby main.rb
*secret data*

IntelのIvy Bridge以降のCPUやRaspberry Pi, Apple A7以降のプロセッサには、熱雑音を利用して物理的に乱数を発生させるハードウェア乱数生成器が備わっている

rubyの安全な乱数: securerandom

require 'securerandom'
hex = SecureRandom.hex(32)
print hex

vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ ruby main.rb
1fbd11b0d5588de19571e3679ee86387d2449b6d376f6211498e4dbd2557fabd

bitcoin-ruby

$ sudo apt-get install git gcc build-essential libreadline-dev zlib1g-dev
$ sudo apt-get install libssl1.0-dev
$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
$ echo ‘export PATH=”$HOME/.rbenv/bin:$PATH”‘ >> ~/.bash_profile
$ echo ‘eval “$(rbenv init -)”‘ >> ~/.bash_profile
$ exec $SHELL -l

vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ rbenv -v
rbenv 1.1.2-11-gc46a970
vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ rbenv install 2.0.0-p643
Downloading ruby-2.0.0-p643.tar.bz2…
-> https://cache.ruby-lang.org/pub/ruby/2.0/ruby-2.0.0-p643.tar.bz2
Installing ruby-2.0.0-p643…

WARNING: ruby-2.0.0-p643 is past its end of life and is now unsupported.
It no longer receives bug fixes or critical security updates.

Installed ruby-2.0.0-p643 to /home/vagrant/.rbenv/versions/2.0.0-p643

vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ rbenv rehash
vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ rbenv versions
* system (set by /home/vagrant/.rbenv/version)
2.0.0-p643
vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ rbenv global 2.0.0-p643
vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ ruby -v
ruby 2.0.0p643 (2015-02-25 revision 49749) [x86_64-linux]

なんかエラーが出ている

[vagrant@localhost rails]$ gem install pg -v ‘1.1.4’
Building native extensions. This could take a while…
ERROR: Error installing pg:
ERROR: Failed to build gem native extension.

current directory: /home/vagrant/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/pg-1.1.4/ext
/home/vagrant/.rbenv/versions/2.3.1/bin/ruby -I /home/vagrant/.rbenv/versions/2.3.1/lib/ruby/site_ruby/2.3.0 -r ./siteconf20190809-24267-2gatu1.rb extconf.rb
checking for pg_config… no
No pg_config… trying anyway. If building fails, please try again with
–with-pg-config=/path/to/pg_config
checking for libpq-fe.h… no
Can’t find the ‘libpq-fe.h header
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers. Check the mkmf.log file for more details. You may
need configuration options.

Provided configuration options:
–with-opt-dir
–without-opt-dir
–with-opt-include
–without-opt-include=${opt-dir}/include
–with-opt-lib
–without-opt-lib=${opt-dir}/lib
–with-make-prog
–without-make-prog
–srcdir=.
–curdir
–ruby=/home/vagrant/.rbenv/versions/2.3.1/bin/$(RUBY_BASE_NAME)
–with-pg
–without-pg
–enable-windows-cross
–disable-windows-cross
–with-pg-config
–without-pg-config
–with-pg_config
–without-pg_config
–with-pg-dir
–without-pg-dir
–with-pg-include
–without-pg-include=${pg-dir}/include
–with-pg-lib
–without-pg-lib=${pg-dir}/lib

To see why this extension failed to compile, please check the mkmf.log which can be found here:

/home/vagrant/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/extensions/x86_64-linux/2.3.0-static/pg-1.1.4/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in /home/vagrant/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/pg-1.1.4 for inspection.
Results logged to /home/vagrant/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/extensions/x86_64-linux/2.3.0-static/pg-1.1.4/gem_make.out
[vagrant@localhost rails]$ find ~/.rbenv | grep mkmf.log
/home/vagrant/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/extensions/x86_64-linux/2.3.0-static/msgpack-1.3.1/mkmf.log
/home/vagrant/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/extensions/x86_64-linux/2.3.0-static/pg-1.1.4/mkmf.log
/home/vagrant/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/extensions/x86_64-linux/2.3.0-static/nio4r-2.4.0/mkmf.log
/home/vagrant/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/extensions/x86_64-linux/2.3.0-static/ffi-1.11.1/mkmf.log
/home/vagrant/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/extensions/x86_64-linux/2.3.0-static/nokogiri-1.10.3/mkmf.log
[vagrant@localhost rails]$ cat /home/vagrant/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/extensions/x86_64-linux/2.3.0-static/pg-1.1.4/mkmf.log
find_executable: checking for pg_config… ——————– no

——————–

find_header: checking for libpq-fe.h… ——————– no

“gcc -o conftest -I/home/vagrant/.rbenv/versions/2.3.1/include/ruby-2.3.0/x86_64-linux -I/home/vagrant/.rbenv/versions/2.3.1/include/ruby-2.3.0/ruby/backward -I/home/vagrant/.rbenv/versions/2.3.1/include/ruby-2.3.0 -I. -I/home/vagrant/.rbenv/versions/2.3.1/include -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wimplicit-function-declaration -Wdeprecated-declarations -Wno-packed-bitfield-compat conftest.c -L. -L/home/vagrant/.rbenv/versions/2.3.1/lib -Wl,-R/home/vagrant/.rbenv/versions/2.3.1/lib -L. -L/home/vagrant/.rbenv/versions/2.3.1/lib -fstack-protector -rdynamic -Wl,-export-dynamic -Wl,-R/home/vagrant/.rbenv/versions/2.3.1/lib -L/home/vagrant/.rbenv/versions/2.3.1/lib -lruby-static -lpthread -lrt -ldl -lcrypt -lm -lc”
checked program was:
/* begin */
1: #include “ruby.h”
2:
3: int main(int argc, char **argv)
4: {
5: return 0;
6: }
/* end */

“gcc -E -I/home/vagrant/.rbenv/versions/2.3.1/include/ruby-2.3.0/x86_64-linux -I/home/vagrant/.rbenv/versions/2.3.1/include/ruby-2.3.0/ruby/backward -I/home/vagrant/.rbenv/versions/2.3.1/include/ruby-2.3.0 -I. -I/home/vagrant/.rbenv/versions/2.3.1/include -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wimplicit-function-declaration -Wdeprecated-declarations -Wno-packed-bitfield-compat conftest.c -o conftest.i”
conftest.c:3:22: error: libpq-fe.h: そのようなファイルやディレクトリはありません
checked program was:
/* begin */
1: #include “ruby.h”
2:
3: #include /* end */

——————–
え?

bundle install

[vagrant@localhost ruby3]$ bundle install
Fetching gem metadata from https://rubygems.org/...........
Fetching version metadata from https://rubygems.org/.
Using json 1.8.3
Installing multi_xml 0.5.5
Installing rack 1.6.4
Installing tilt 2.0.2
Using bundler 1.13.6
Installing httparty 0.13.7
Using rack-protection 1.5.3
Using sinatra 1.4.7
Bundle complete! 3 Gemfile dependencies, 8 gems now installed.
Use `bundle show [gemname]` to see where a bundled gem is installed.
Post-install message from httparty:
When you HTTParty, you must party hard!
get '/product' do
	...
	@products = []
	LOCATIONS.each do |location|
	 @product.push DATA.select { |product| product['location'] == location }.sample
end
<% @product.each do |product| %>
<a href='/products/location<%= product&#91;location&#93; %>'>
<div class='product'>
	<div class='thumb'>
		<img src='<%= product&#91;'url'&#93; %>'>
	</div>
	<div class='caption'>
		<%= product&#91;'location'&#93; != 'us' ? product&#91;'location'&#93;.capitalize : product&#91;'location'&#93;.upcase %>
		</div>
	</div>
</a>
<% end %>
get '/products/location/:location' do
	DATA = HTTParty.get('https://fomotograph-api.udacity.com/products.json')['photos']
	@products = DATA.select{ |product| product['location'] == params[:location]}
	erb "<!DOCTYPE html>..."
end


get '/products/:id' do
	DATA = HTTPartyp.get('https://hogehoge/products.json')['photos']
	@product = DATA.select{ |prod| prod['id'] == params[:id].to_i }.first
	erb "<!DOCTYPE html> ..."
end	
class Product

	url = 'https://fomotograph-api.com/product.json'
	DATA = HTTParty.get(url)['photos']
end
require 'HTTParty'
require 'json'

class Product

	url = 'https://fomotograph-api.com/product.json'
	DATA = HTTParty.get(url)['photos']

	def initialize(product_data = {})
	@id = product_data['id']
	@title = product_data['title']
	@location = product_data['location']
	@summary = product_data['summary']
	@url = product_data['url']
	@price = product_data['price']
	end

	def self.all
		DATA.map { |product| new(product) }
	end

	def self.sample_locations
		@products = []
		LOCATIONS.each do |location|
		@products.push self.all.select { |product| product.location == location }.sample_locations
		end
		return @product
	end

	def self.find_by_location(location)
		self.all.select { |product| product.location == location }
	end
end
{
	"id"=>27, "title"=>"worlds end", "summary"=>"travel tothe end ...",
	"location"=>"scotland", "price"=>37, "url"=>"/images/scotland/worlds-end.jpg"
}

controller

get '/products' do
	@products = Product.all
	erb :products
end