43
40

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Railsメモ - 初心者を抜け出す助けになるかもまとめ

Last updated at Posted at 2016-04-19

完全に自分用にまとめたのですが、初心者には盲点になりそうなところが多くもしかしたら役立つかもしれないな、ということで公開。修正・アドバイス等あればコメントください。

主には、『たのしいRuby』と『Ruby on Rails4 アプリケーションプログラミング』のまとめです。

たのしいRuby

require

requireは使いたいライブラリのファイルを読み込む。
例:"uri"
メモ:以下のモジュールのincludeなどがクラスに対するものだとしたら、ファイルに対するincludeみたいなものかな?

モジュール

クラスとの違い

モジュールはメソッドを提供し、クラスに似ているが以下の点で違う

  • インスタンスを作成できない
  • 継承できない

includeとextend

基本的にはRailsのヘルペーみたいにどこでも(?)呼び出せる

module Test
	def explain(name)
		p "#{name}さん、これはテストです"
	end
end

Test::explain("田中") #=> "田中さん、これはテストです"

includeすると、インスタンスメソッドに追加される

module Test
	def explain(name)
		p "#{name}さん、これはテストです"
	end
end

class MyClass
include Test

end

test = MyClass.new
test.explain("田中") #=> "田中さん、これはテストです"

extendすると、クラスメソッドに追加される


module Test
	def explain(name)
		p "#{name}さん、これはテストです"
	end
end

class MyClass
extend Test

end

MyClass.explain("田中") #=> "田中さん、これはテストです"

例外処理

基本系

begin
	# 通常の処理
	raise "メッセージ" # RuntimeErrorが発生
	raise 例外クラス # 指定した例外の発生
	raise 例外クラス, "メッセージ" #指定した例外を発生させ、そのオブジェクトにメッセージをセット
	raise # RuntimeError
rescue
	# error処理
	# $で例外オブジェクトにアクセスできる
	# $! => 最後に発生した例外 $@ => 最後に発生した例外の位置に関する情報
	raise # $!をもう一度発生させる
ensure
	# 例外の有無にかかわらず実行される処理
end

例外オブジェクト

呼び出せるメソッド

  • class : 例外の種類
  • message : 例外のメッセージ
  • backtrace : 例外が発生した位置に関する情報

ブロック

def total(from, to)
	result = 0
	from.upto(to) do |num|
		if block_given?          # ブロックが渡されていたら
			result += yield(num) # numを引数として渡されたブロックを実行
		else
			result += num
		end	
	end
	return result
end

p total(1, 10)                    # 1から10の和 => 55
p total(1, 10) { |num| num ** 2 } # 1から10の2乗の値の和 => 385

ブロックの中でbreakを呼びと、nilになる。break 0など値を渡すと戻り値が設定される

あとは辞書的に使おう笑

Rails アプリケーションプログラミング の学びまとめ

View

debugを使おう

debug(@items)といった形で、変数の中身をviewに表示できる。

簡単な部分テンプレートのcapture

- @current = capture do
	= "ただいまの時刻は#{Time.now}です。"

= @current
div.container = @current

Model

Validation

こうやると綺麗にかけるのか

class Book < ActiveRecord::Base
	validates :isbn,
		presence:   true,
		uniqueness: true,
		length:     { is: 17 },
		format:     { with: /¥a[0-9]/ }
	validates :title
		# ...(省略

データベースに関連づかないモデルを定義する

フォームからの入力を検証したい時など

# app/models/search_keyword.rb
class SearchKeyword
	include ActiveModel::Model
	
	attr_accessor :keyword
	
	validates :keyword, presene: true
end

# record_controller

def keywd
	@search = SearchKeyword.new
end

def keywd_process
	@search = SearchKeyword.new(params[:search_keyword])
	if @search.valid? # ここでバリデーターを呼び出す。
		render text: @search.keyword
	end
end

		

Controller

基本認証:簡易なログイン実装

ひとまず管理者のみにしたいときとか。

class CtrlController < ApplicationController

	before_action :auth, only: :index
	
	private
		
	def auth
		# 認証に使う名前とパスワード
		name = 'kimuko'	
		passwd = '8dohardk4kfn45ngiij4359058'
		
		#基本認証を実行
		authentiate_or_request_with_http_basic('Railsbook') do |n, p|
			n == name && Digest::SHA1.hexdigest(p) == passwd
		end
	end
end	

例外処理

application_controller.rb
class ApplicationController < ActionController::Base
	protect_from_forgery with: :exception
	
	rescue_from ActiveRecord::RecordNotFound, with: :id_invalid
	
	private
	
	def id_invalid(e)
		# 404用のビュー
		render 'shared/record_not_found', status: 404
	end

デフォルトではpublic/404.htmlpublic/500.htmlに飛ばされる。

独自のフラッシュメッセージの追加

以下のように追加できる。

class ApplicationController < ActionController::Base
	add_flash_types :info
end

複数コントローラー共通の処理

app/controllers/concernsにまとめる

sample.rb
module Name
	extend ActiveSupport::Concern
	
	included do
		# call_clazz
		before_filter :check_logined
	end
	
	module ClassMethods
		#定義
	end
	
	#インスタンスメソッドの定義
	
	private
	
	def check_logined
	end
end

そして、読み込みたい側でinclude NameとすればOK

ルーティング

namespaceとscopeの違い

namespace:参照コントローラー、URLパターン、Urlヘルパーも変わる(RESTful)
scope module:参照コントローラーは変わるが、その他は変わらない
scopeはコントローラーは変えないが、URLだけ変える

path_name

newやeditなどの標準アクションに関連づいたURLを変更したいならば、:path_namesオプションを指定。これやりたかった...!

resources :reviews, path_names: { new: :insert, edit: :revise }

ネストを浅くするshallowオプション

resources :books do
	resources :reviews, shallow: true
end

こうすると、reviewsリソースがidを受け取らない、index,new,createアクションでのみ:book_idが入り、それ以外は、idのみのパスが出来上がる。

さらにscopeとshallow_pathを利用すると、reviewsリソース時に、books/ではなくb/を指定できたりする。

scope shallow_path: :b do
	resources :books do
		resources :reviews, shallow: true
	end
end

キャッシュについて

サイトのスケーラビリティを考えたら必須の機能。これ以外にもありそうだけど本書ではフラグメントキャッシュを利用。

基本

- cache do
	= Time.new
	br

ビューヘルパーcacheでキャッシュしたい領域を囲うだけ。簡単!!

同一ページでのキャッシュキー

基本的にキャッシュキーで管理しているらしいが、複数のキャッシュが同一ページにあるとキーが重複してしまう、とのこと。なので以下のように指定

- cache(suffix: 'footer') do
	= Time.new
	br

キャッシュキーの複数ページでの共有

同一のキャッシュキーを利用すればOK

キャッシュキーの決め方

モデルを元に

- cache(book) do
	#ビュー

このようにモデルのオブジェクトを渡すとモデル名.id値-updated_at列の値というキーを生成してくれるらしい。これなら更新しててもわかるね。

親子関係にあるモデルにおける注意点
review.rb
class Review < ActiveRecord::Base
	belongs_to :book, touch: true
end

このtouch: trueがあれば、親のupdated_atも更新されるので最新のキャッシュを保てるとのこと。

一覧画面とかは?
- cache(books_cache_key) do

module ExtraHelper
	def books_cache_key
		"books-#{Book.count}-#{Book.maximum(:updated_at).to_i}"
	end
end

ヘルパーを拡張して作っちゃおう。

条件つき
- cache_if(book.published <= Date.today, book)

的な。

※注意:キャッシュはメモリの上限まで累積する。最終アクセス日などから判断して定期的に削除すること

43
40
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
43
40

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?