railsでajaxを使って投稿を削除しフラッシュ表示

#下準備
今回はbootstrap,slimを使ってやっていきます。

とりあえず

```ruby:gemfile
gem 'bootstrap'
gem 'tether-rails'
gem 'popper_js'
gem 'jquery'
gem 'slim-rails'
gem 'html2slim'
```

をbundle installします。

そして

app/assets/javascripts/application.jsに

```javascript:application.js
//= require jquery3
//= require rails-ujs
//= require popper
//= require tether
//= require bootstrap
```

を追加します。

それで

assets/stylesheets/application.cssを

application.scssに名前をかえて

なかに

```scss:application.scss
@import '/*';
@import 'bootstrap';
@import 'tether';
```

でOK


#アプリを作っていく

コマンドで

```
rails g model post body:text
rails db:migrate
rails g controller posts index new
```

をする。


まずroutesの設定をしておく

```ruby:routes.rb
resources :posts
```

と書き加えてroutes.rbの設定はおわり


postに関するアクションを作っていくため

posts_controller.rbの中身を

```ruby:posts_controller.rb

def index 
  @posts = Post.all
end 

def new
  @post = Post.new
end 

def create 
  if Post.create(post_params)
    redirect_to posts_path
  else 
    render :new
  end 
end 


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


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

```


これでとりあえずはindexでは一覧をnewとcreateで作成,destroyで削除の機能を追加できました。

次にview側を作っていきます。


index.html.slimに

```slim:index.html.slim
div.container
  br
  br
  - @posts.each do |post|
    div.border-bottom.form-inline
      p.col-md-10= post.body
      = link_to "削除", post_path(post), class: 'btn btn-sm btn-primary', method: :delete

  br
  br
  = link_to "追加", new_post_path, class: "btn btn-sm btn-success"



```


new.html.slimに

```slim:new.html.slim
div.container
  br
  br 
  = form_with model: @post do |f|
    .form-group
      = f.label :body
      = f.text_field :body, class: "form-control"
    .form-group
      = f.submit "投稿", class: "btn btn-primary"

```


多分これで投稿を行ってそれを表示、削除ができるようになったはずです。


#Ajax機能を追加


つぎに非同期で投稿を削除できるようにしていきます。

まず

index.html.slimの削除ボタンのところを

```slim:index.html.slim
= link_to "削除", post_path(post), class: "btn btn-sm btn-primary", method: :delete, remote: true
```

のように変更します。

何が変わったかというと最後にremote: trueが追加されています。

これで非同期的に投稿を削除できます。

ですがこの状態だと削除した投稿がそのまま画面に表示されたままになっています。


なのでviews/postsに

destroy.js.erbというファイルを作成して

```javascript:destroy.js.erb
$('#post-<%= @post_id %>').html('');
```


と書きます。

このdestroy.js.erbファイルは非同期でdestroyアクションが実行されたときに読み込まれます。

```javascript
$('#post-<%= @post_id %>').html('');
```

はなんかというとidがpost-<%= @post_id %>となっているものを非表示にする処理です。


index.html.slimを

```slim:index.html.slim
div.container
    div id="alert-message"
    br
    br 
    br
    - @posts.each do |post|
        div id="post-#{post.id}" <= 追加
            div.border-bottom.form-inline
                p.col-md-10= post.body 
                = link_to "削除", post_path(post), class: "btn btn-sm btn-primary", method: :delete, remote: true
    br 
    br 
    br 
    br 
    = link_to "post追加", new_post_path 
```


のようにすることで削除ボタンが押されたらその投稿が非表示にすることができます。

destroy.js.erbにpostのidを渡すために


posts_controller.rbのdestroyアクションに

```ruby
@post_id = @post.id
```

を追加します。

これで削除ボタンを押したら非同期で投稿が削除されます。


#flash機能の追加

次にflash機能を追加していきます。

まずdestroyアクションに

```
@msg = "削除が成功"
```

を追加します。

そして

destory.js.erbファイルに


```javascript:destroy.js.erb

$('#alert-message').html('<div class="alert alert-success"><%= @msg %></div>')
```

と書けば削除ボタンが押されたときにid=alert-messageに@msgを表示させることができます。


index.html.slimに

```slim:index.html.slim

div.container
    div id="alert-message" <= 追加
    br
    br 
    br
    - @posts.each do |post|
        div id="post-#{post.id}"
            div.border-bottom.form-inline
                p.col-md-10= post.body 
                = link_to "削除", post_path(post), class: "btn btn-sm btn-primary", method: :delete, remote: true
    br 
    br 
    br 
    br 
    = link_to "post追加", new_post_path 


```






とすることで削除したときにフラッシュが表示されます。


うまくいけばこんな感じになるはず


![ajax.png](https://qiita-image-store.s3.amazonaws.com/0/207921/e0b0a8d8-a1b2-e005-814b-ba75f3666f01.png)



なにか間違っているところがあればご指摘いただけると助かります。

おわり。