Edited at

アプリケーションの作成3

More than 1 year has passed since last update.

db/migrate/xxx_create_comments.rbの次のコードを変更。

PostとCommentは1対多の関係なので、多側のCommentにpost_idという外部キーのフィールドが必要となる。

UserとCommentは1対多の関係なので、多側のCommentにuser_idという外部キーのフィールドが必要となります。


db/migrate/xxx_create_comments.rb


t.text :message
t.integer :post_id
t.integer :user_id

rails db:migrateを実行。

データベースにテーブルを作成します。

rails db:migrate

app/models/post.rbのPostクラスに次のコード追加。


app/models/post.rb


has_many :comments, :dependent => :destroy

PostとCommentは1対多の関係があり、Postは1側なのでリレーションの定義ではhas_manyを使います。また、postsテーブルのデータを削除した場合に関連するcommentsテーブルの全データを削除するために:dependent=> :destroyを指定しています。

app/views/commentsフォルダ作成。

comments配下にnew.html.erbを作成し、次のコードを追加。


app/views/comments/new.html.erb


<% content_for :title do %>
コメント作成
<% end %>

<%= render 'layouts/error_message', object: @comment %>
<div class=
"row">
<div class="col-md-8 col-md-offset-2">
<h1>コメント作成</h1>
<form action="<%= post_comments_path(@postId) %>" method="post">
<div class="form-group">
<label for="Message">メッセージ</
label>
<textarea class="form-control" name="message" id="Message" rows="5" placeholder="Your Comment"></textarea>
</
div>
<button type="submit" class="btn btn-primary">送信</button>
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
</
form>
</div>
</
div>


$postIdをcreateアクションに渡しています。(CommentとPostのデータを関連づけるために使います(関連付けはcreateアクションで行う))

app/controllers/comments_controller.rbを作成し、次のコードを入力。


app/controllers/comments_controller.rb

class CommentsController < ApplicationController

before_action :logged_in_user

def new
# necessary for validation error message
@comment = Comment.new
@postId = params[:post_id]
end

def create
@comment = Comment.new
@comment.message = params[:message]
@comment.post_id = params[:post_id]
@comment.user_id = current_user.id

if @comment.save
redirect_to post_path(:id => params[:post_id])
else
render 'new'
end
end
end


newアクションでshow.html.erbから受け取った$post_idをnew.html.erbに渡しています。(CommentとPostのデータを関連付けるために使います(関連付けはcreateアクションで行う))

createアクションでは次の箇所で関連付けを行っています。

@comment.post_id = parmas[:post_id]

→CommentとPostのデータが関連付けられます。

@comment.user_id = current_user.id

→CommentとUserのデータが関連付けられます。

config/routes.rbのpost箇所を次のコードのように変更。

CommentsControllerのnewとcreateアクションのルートを定義しています。


config/routes.rb


resources :posts, only: [:index, :new, :create, ;show, :destroy] do
resources :comments, only: [:new, :create]
end

app/views/posts/show.html.erbの次のコードを変更。

@post.idをnewアクションに渡してします。(CommentとPostのデータを関連付けるために使います(関連付けはcreateアクションで行う))


app/views/posts/show.html.erb


<a helf="<%= new_post_comment_path(:post_id => @post.id) %>"
class="btn btn-primary btn-space-20 pull-right">コメント</a>

app/views/posts/show.html.erbに次のコードを追加

CommentとUserはリレーションを持っているため、comment.user.imageのような参照ができます。


app/views/posts/show.html.erb


<hr>

<% @post.comments.each do |comment| %>
<div class="media">

<div class="media-left">
<a href="#">
<img class="media-object img-circle" src="<%= "/images/#{comment.user.image}" %>" width=64 height=64>
</a>
</
div>
<div class="media-body">
<h5 class="media-heading"><%= comment.user.name %> <small><%= comment.created_at %></small></h5>
<p><%= comment.message %></
p>
</div>
</
div>
<% end %>


app/views/layouts/_navbar.htmlerbに次のコードを追加

検索ワードを入れるためのフォームをNavbarに追加します。


app/views/layouts/_navbar.htmlerb


<form action="<%= posts_path %>" class="navbar-form navbar-left">
<div class="form-group">
<input type="text" name="word" class="form-control" placeholder="Search Messages">
</div>
<button type="submit" class="btn btn-default">投稿検索</
button>
</form>


app/controllers

/posts_controller.rbに次のコードに変更

postsテーブルのmessageフィールドのデータの中で検索ワードが含まれているものが抽出される。

ActiveRecordでLIKE検索

http://stackoverflow.com/questions/25416667/rails-4-prevent-sql-injection-using-like-operator-in-sql-query


app/controllers/posts_controller.rb


def index
if params[:word].present?
@posts = Post.where("message like ?",
"%#(params[:word])%").order(created_at: :desc)
else
@posts = post.all.order(created_at: :desc)
end
end