TECH EXPERT 48日目

TECH::EXPERT

rails

render

render :show
render action: :show
render "show"
render "show.html.erb"
render action: "show"
render action: "show.html.erb"

form_with

renderで画像遷移しない

form_withは標準でremote: trueになっていて非同期通信をしている。
このため、createアクション等でrenderを返す場合に、画面遷移しない。
local: trueを指定すると、同期通信になるためrenderされるようになる。

= form_with(model: @user, url: root_path, local: true) do |f|
  = f.submit

devise

スコープの変更

既存のアクションのスコープを変更する場合

  devise_for :users, :controllers => {
    :registrations => 'users/registrations'
   }
         new_user_session GET    /users/sign_in(.:format)                                                                 devise/sessions#new
             user_session POST   /users/sign_in(.:format)                                                                 devise/sessions#create
     destroy_user_session DELETE /users/sign_out(.:format)                                                                devise/sessions#destroy
        new_user_password GET    /users/password/new(.:format)                                                            devise/passwords#new
       edit_user_password GET    /users/password/edit(.:format)                                                           devise/passwords#edit
            user_password PATCH  /users/password(.:format)                                                                devise/passwords#update
                          PUT    /users/password(.:format)                                                                devise/passwords#update
                          POST   /users/password(.:format)                                                                devise/passwords#create
 cancel_user_registration GET    /users/cancel(.:format)                                                                  users/registrations#cancel
    new_user_registration GET    /users/sign_up(.:format)                                                                 users/registrations#new
   edit_user_registration GET    /users/edit(.:format)                                                                    users/registrations#edit
        user_registration PATCH  /users(.:format)                                                                         users/registrations#update
                          PUT    /users(.:format)                                                                         users/registrations#update
                          DELETE /users(.:format)                                                                         users/registrations#destroy
                          POST   /users(.:format)                                                                         users/registrations#create

新たなアクションのスコープを指定する場合

  devise_scope :user do
    get '/users/sign_up/sns_confirmation', to: 'devise/registrations#sns_confirmation'
    get '/users/sign_up/phone_confirmation', to: 'devise/registrations#phone_confirmation'
    get '/users/sign_up/user_information_confirmation', to: 'users/registrations#user_information_confirmation'
    get '/users/sign_up/shipping_confirmation', to: 'devise/registrations#shipping_confirmation'
    get '/users/sign_up/payment_confirmation', to: 'devise/registrations#payment_confirmation'
  end
             users_sign_up_sns_confirmation GET    /users/sign_up/sns_confirmation(.:format)                                                users/registrations#sns_confirmation
           users_sign_up_phone_confirmation GET    /users/sign_up/phone_confirmation(.:format)                                              users/registrations#phone_confirmation
users_sign_up_user_information_confirmation GET    /users/sign_up/user_information_confirmation(.:format)                                   users/registrations#user_information_confirmation
        users_sign_up_shipping_confirmation GET    /users/sign_up/shipping_confirmation(.:format)                                           users/registrations#shipping_confirmation
         users_sign_up_payment_confirmation GET    /users/sign_up/payment_confirmation(.:format)                                            users/registrations#payment_confirmation

session

sessionに情報を保存する場合は以下のようにする。

session[:user_id] = user.id

paramsの内容を一旦、sessionに保存する場合

paramsは以下のクラス

<ActionController::Parameters>

sessionは以下のクラス

#<ActionDispatch::Request::Session:0x00007fe98b371ff0 ...>
session = params.permit()
とすると、sessionという変数は<ActionController::Parameters>になってしまう。
Sessionクラスのsessionとは別物な感じ。
これではページ遷移後に情報が保持されない。

paramsを.to_hでハッシュに変えて代入してやればSessionクラスとして代入できる。
session = user_information_params.to_h

なおparams.to_hでハッシュ化されるのはpermitされた項目のみ。
params.permit.to_hとしないと空のハッシュになる。

devise

user exists

空のデータベースに対して登録しようとした時、下記のエラーが出る。
validationエラーの可能性が高く、多いのはdeviseの標準のpassword8文字以上を満たしていない場合。

User Exists (0.5ms)[0m  [1mSELECT 1 AS one FROM "users" WHERE "users"."email" = 'hoge@mst.com' LIMIT 1

controllerのoverride

  devise_for :users, controllers: {
    registrations: 'users/registrations'
  }

validation

カスタムバリデーション

app/validatorsフォルダを作成し、配下にvalidationファイルを設置する。

user_validator.rb

class UserValidator < ActiveModel::Validator
  def validate(record)
    items = [record.nickname, record.email, record.birthday]
    return if items.any?(:present?)
    record.errors[:base] << '入力漏れがあります'
  end
end

定義したvalidatorを使うにはvalidate_withで呼び出す。

model   user.rb

class User < ApplicationRecord
  validates_with UserValidator
end

valid?

条件分岐する場合にはsaveと違い、if createだとcreateに失敗してもtrueとなるため、valid?でバリデーションをかけて評価する。

def create
  if User.create(user_information_params).valid?
    redirect_to root_path
  else
    render "phone_confirmation.html.haml"
  end
end

error

Undefined method users_url

deviseもコントローラーをオーバーライドした際に、sign_up後の遷移先に移る際にこのエラーがでた。
after_sign_up_path_forを書き換えてもエラーが消えなかったため、createアクションをオーバーライドして、redirectするように変更して解消した。
エラーの原因や解決方法がよくわからない。

python

switch文

存在しない。if文の列挙で対応する。

etreeクラス

.get()

nodeのattributeを.attribで取り出した際にはetreeクラスとなるため、stringに対するメソッドが使えない。{hoge: fuga, hoge2: fuga2,,,}
attribute内のvalueを取り出すためにr.get(“hoge”)と指定するとfugaを引ける。

root = read_xml(path)
for i,r in enumerate(root):
  r.get("contextRef")

css

!important

設定を優先させる。

height: 60px !important;

コメント