.save

セーブがしたいんです…

rspec エラーまとめ

・エラー文

Web Console is activated in the test environment, which is
usually a mistake. To ensure it's only activated in development
mode, move it to the development group of your Gemfile:

    gem 'web-console', group: :development

If you still want to run it the test environment (and know
what you are doing), put this in your Rails application
configuration:

    config.web_console.development_only = false

・以下を参考に解決を試みる stonebeach-dakar.hatenablog.com

手順1
config/application.rb

config.web_console.development_only = false

以上を追加

手順2
gemfile

gem 'web-console', '~> 2.0'

しかし、以上ではうまくいかなかった。

・他の原因 DBを作っていなかったことをがわかり、作成。
すると、

Running via Spring preloader in process 3663

User
  #create
    is invalid without a nickname

Finished in 0.00178 seconds (files took 4.23 seconds to load)
1 example, 0 failures

かんせー

レビュー反省 2016 12 20

permitでuser_id、group_idを許すのか、mergeでuser_id、group_idを加えるのかどちらかにしましょう。

params.require(:message).permit(:message, :user_id, :group_id).merge(user_id: current_user.id, group_id: params[:group_id])

 

elseの後、改行しましょう

if @message.save!
redirect_to group_path(@group)
else

redirect_to :back, alert: 'メッセージを入力してください'

こうするといい。

 

save!は保存に失敗したときに例外を発生させます。単純にfalseが返ってきて欲しい時はsaveを使いましょう

 

現在はchatの画面をgroups_cpntrollerのshowで実装していると思います。しかし、chat画面はmessageの一覧が表示されていると考えてmessages_controllerのindexを使って実装する方が良いかなと思います。
ルーティングでmessageをネストしているのでmessages_controllerでもgroup_idを使うことができます。そのgroup_idを使ってグループを取得し、関連付けられたメッセージを一覧で表示してみましょう。

 

messageコントローラにて、投稿されたmessageの表示を行うようにする。

 

やり方

1、messageコントローラにindexアクションを作る。

2、中身を作る。役割は以下のとおり。

def index
@group = Group.find(params[:group_id]) #グループのページにアクセスした時に、そのグループの番号を受け取る
@messages = @group.messages #上で受け取ったグループの番号に関連したmessageテーブルの値を取得する
@message = Message.new #form_forに入力される値を受け取るための箱を用意する
end

3、viewをmessagesフォルダに作る。viewで使っている変数で変える必要がある部分は変える。

 

・changeについて

コミットのメッセージで迷うから。

detail.chiebukuro.yahoo.co.jp

 

・リダイレクトの際に、いちいち変数でgroup_idを取得して飛ばす必要はない。

def create 

message = Message.new(create_params)
group_id = params[:group_id] #リダイレクトをするために、現在のページのgroup_idを取得する

if message.save
redirect_to group_messages_path(group_id)

 

これを・・・・・・・・・

 

redirect_to group_messages_path(params[:group_id])

 

こうする。

レビューの反省 2016 12 19

@groupだとgroupのインスタンスが入っている様に見えてしまうので変数名を変えましょう

 

def create
  @message = Message.new(create_params) #入力された値を保存する
  @group = params[:group_id] #リダイレクトをするために、現在のページのgroup_idを取得する

 

・save!は保存に失敗したときに例外を発生させます。単純にfalseが返ってきて欲しい時はsaveを使いましょう

参考

d.hatena.ne.jp

 

・elseの後、改行しましょう

 

@group = params[:group_id] #リダイレクトをするために、現在のページのgroup_idを取得する
if @message.save!
redirect_to group_path(@group)
else redirect_to :back, alert: 'メッセージを入力してください'

 

・permitでuser_id、group_idを許すのか、mergeでuser_id、group_idを加えるのかどちらかにしましょう。

 

def create_params
params.require(:message).permit(:message, :user_id, :group_id).merge(user_id: current_user.id, group_id: params[:group_id])

レビュー反省 2016 12 18

・シンボル型での記述をメインで使うこと

render 'edit' より、render :editなどの方が見やすい。

 

hamlでは式展開ではなく、rubyタグを使う。

%p #{current_user.name}ではなく、%p= current_user.nameで書く。

 

・レビューを受けた際は同じような記述が他にもないか必ず確認しましょう!

 

・prefixを使用してパスを指定する場合はedit_group_path(@group)というように.idを省略して書くことが出来ます。

EX

= link_to 'Edit', edit_group_path(@group.id) を = link_to 'Edit', edit_group_path(@group) にする

 

 

rails 部分テンプレートの使い方 まとめ

1、部分テンプレートの作り方

 

 _ファイル名.html.haml(or erb)

 

 これを使いたいコントローラーが管理するviewフォルダにいれる。

 

2、部分テンプレートの呼び出し方

 

 = render partial: "1で作った「ファイル名」の部分"

 

 部分テンプレートの内容を繰り返し表示させる場合は、collection: @変数名

 

追記 = render "group" に省略することができた。

 

EX

 = render partial: "group", collection: @groups

 

追記  partial: の指定は無くてもよかった。

 

 

参考

Railsでパーシャルを使って、似たようなコードを共通化したい | Ruby on Railsサービス開発逆引き辞典

 

qiita.com

 

render - リファレンス - - Railsドキュメント

チャットアプリケーション制作記録1 動作考察

class GroupsController < ApplicationController

  before_action :set_group, only:[:show, :edit, :update]

  def index
    @groups = current_user.groups
  end

  def new
    @group = Group.new
  end

  def create
    @group = Group.new(group_params)
    if @group.save
      redirect_to root_path, notice: 'グループが作成されました'
    else
      flash.now[:alert] = "グループ名を入力してください"
      render :new
    end
  end

  def edit
  end

  def update
    if @group.update(group_params)
      redirect_to group_path(@group), flash: {notice: 'グループ情報が変更されました。'}
    else
      render 'edit'
      flash[:alert] = 'グループ情報の変更に失敗しました'
    end
  end

  def show
    @groups = current_user.groups
  end

  private
  def group_params
    params.require(:group).permit(:name, { user_ids:[] })
  end

  def set_group
     @group = Group.find(params[:id])
  end
end

各アクションの動作について

index

  def index  
    @groups = current_user.groups  
  end  

current_userに紐付いたgroupsテーブルの値を全て@groupに代入する。

    %ul.chat__side_bar__groups
      - @groups.each do |group|
        %li.chat__side_bar__groups__group
          = link_to group_path(group.id) do
            %p.chat__side_bar__groups__group_name  
              = group.name
            %p.chat__side_bar__groups__group_message 最新メッセージ

値は以上のように、eachで出力する。

new create

  def new
    @group = Group.new
  end

  def create
    @group = Group.new(group_params)
    if @group.save
      redirect_to root_path, notice: 'グループが作成されました'
    else
      flash.now[:alert] = "グループ名を入力してください"
      render :new
    end
  end

  private
  def group_params
    params.require(:group).permit(:name, { user_ids:[] })
  end

newアクションはグループ作成時に空のインスタンスを作成する。作成された情報はここに入る。
createアクションは空のインスタンスに、ストロングパラメータ取得された、:name,user_ids:[]を入れ、正しく入力されたら値を保存し、そうでない場合はnewアクションに戻す。

edit update

before_action :set_group, only:[:show, :edit, :update]

  def edit
  end

  def update
    if @group.update(group_params)
      redirect_to group_path(@group), flash: {notice: 'グループ情報が変更されました。'}
    else
      render 'edit'
      flash[:alert] = 'グループ情報の変更に失敗しました'
    end
  end

  def set_group
     @group = Group.find(params[:id])
  end

編集画面に移動する際に、editアクションは入力されたidに対応する値をgroupsテーブルから持ってくる。
編集が完了した際に、updateアクションがそれらを保存する。

show

before_action :set_group, only:[:show, :edit, :update]
  
  def show
    @groups = current_user.groups
  end

  def set_group
     @group = Group.find(params[:id])
  end

ログイン中のユーザーに紐付いた値をgroupsテーブルから取得し、@groupsに代入する。