LoginSignup
0
0

More than 1 year has passed since last update.

#1 RailsとVue.jsでモーダルウィンドウを実装

Posted at

せっかくdrinks/show.html.erbをapp.vueに記述しなおしたので、
モーダルウィンドウ的なものを実装したい。
つまり、投稿一覧から投稿を押すと、そのままapp.vueが画面遷移なしに表示されるとか
をやってみたい。
だけど、投稿一覧はerbで実装されてるので、そこからvueコンポーネントを表示できるのか。。。

https://qiita.com/t1gert1ger/items/b048a5fd81dc5a8fbfc8
自分がやりたいような記事はあった。

いや、てかやったことあったな。

application.html.erb

 <%= javascript_pack_tag 'footer' %>
footer.vue

<template>
<div class="footer">
  <div>
    <router-link to="/contact">お問い合せ</router-link>
  </div>
  <div>
    <router-link to="#">私たちについて</router-link>
  </div>
  <div>
    <router-link to="#">コーヒーをもっと知る</router-link>
  </div>
  <div>
    <router-link to="/about_coffee_passport">Coffee Passport とは</router-link>
  </div>
</div>
</template>
footer.js

import Vue from 'vue/dist/vue.esm.js'
import Router from './router/router'
import footer from './components/footer.vue'




var app = new Vue({
  router: Router,
  el: '#footer',
  components: {
    'navbar': footer,
  }
});


router.js

import Vue from 'vue/dist/vue.esm.js'
import VueRouter from 'vue-router'
import Contact from '../components/contact.vue'
import About from '../components/about_coffee_passport.vue'

Vue.use(VueRouter)

export default new VueRouter({
  mode: 'history',
  routes: [
    { path: '/contact', component: Contact },
    { path: '/about_coffee_passport', component: About}
  ],
})
contact.vue

<template>
  <div>
    <form class="contact-form"  action="https://formspree.io/f/xvovebqd" method="post">
      <input type="hidden" name="_subject" value="お問い合せ" >
      <input type="hidden" name="_next" value="https://www.youtube.com/" >

      <label for="email"> メールアドレス</label>
      <input name="Email" id="email" type="email" placeholder="coffee@gmail.com" required>

      <label for="name">お名前</label>
      <input type="name"  placeholder="珈琲太郎" required>

      <label for="context"> お問合わせ内容</label>
      <textarea name="context" id="" cols="30" rows="10"></textarea>

      <button class="contact-submit"  type="submit">送信する</button>
    </form>

  </div>
</template>

こうすると、お問い合わせページが表示される。

ただこれは、router-linkで表示させていたので、erbにrouter-linkをつかえれば話はべつ。。。

もしくは、投稿一覧ページをvueで実装するか。。。って感じ。。。

ってことで、投稿一覧ページをvueで実装

route.rb

  namespace :api, format: 'json' do
    resources :drinks, only: [:index,:show]
  end
api/drinks_controller.rb

class Api::DrinksController < ApplicationController

  include SessionsHelper

  def index
    def index
      @user = current_user

      following_ids = 'SELECT followed_id FROM relationships WHERE follower_id = :user_id'

      @drinks = Drink.includes(:user ,{image_attachment: :blob})
                      .where.not(user_id: 6)
                      .where("user_id IN (#{following_ids}) OR user_id = :user_id", user_id: @user.id)
                      .order('drinks.created_at DESC')

      @random_drinks = Drink.includes(:user, {image_attachment: :blob}).order('RAND()').limit(5)
    end
  end
app/view/api/drinks/index.json.jbuilder
json.array! @drinks do |drink|
  json.name             drink.name
  json.explain          drink.explain
  json.region_name      drink.region.name
  json.acidity_name     drink.acidity.name
  json.body_name        drink.body.name
  json.processing_name  drink.processing.name
  json.likes_count      drink.likes_count
  json.user_id          drink.user_id
  json.image rails_blob_url(drink.image) if drink.image.attached?
end
3000/api/drinks

[{"name":"ddd","explain":"dddddd","region_name":"---","acidity_name":"---","body_name":"---","processing_name":"---","likes_count":1,"user_id":7,"image":"http://localhost:3000/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBGQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--a5cbc36b9182e1ffa204bbf8cf5678f1790eec3f/anastasiia-chepinska-lcfH0p6emhw-unsplash.jpg"},{"name":"SSS","explain":"ddddd","region_name":"---","acidity_name":"---","body_name":"---","processing_name":"---","likes_count":1,"user_id":7,"image":"http://localhost:3000/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBFdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--298eaaf8b1f1cd2a3d527cd25f42ee99cac79e9f/anastasiia-chepinska-lcfH0p6emhw-unsplash.jpg"},{"name":"aaaaa","explain":"#sssss","region_name":"ラテンアメリカ","acidity_name":"MEDIUM(ほどよい)","body_name":"LIGHT(軽い)","processing_name":"WASHED(水洗式)","likes_count":1,"user_id":7,"image":"http://localhost:3000/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBFZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--7c49e17b8aeaf1a37ad4fec0714d0b2b128225e5/anastasiia-chepinska-lcfH0p6emhw-unsplash.jpg"},{"name":"サンプル","explain":"#ああああ","region_name":"アジア、太平洋","acidity_name":"MEDIUM(ほどよい)","body_name":"LIGHT(軽い)","processing_name":"SEMI-WASHED(半水洗式)","likes_count":0,"user_id":7,"image":"http://localhost:3000/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBFUT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--aeff59b28c839b85929e21719b4095174c835734/anastasiia-chepinska-lcfH0p6emhw-unsplash%20(1).jpg"}]

jsonデータを取ってくることができた!!

だがしかし、v-forでリストレンダリングしなければならないので、このような形式でいいのだろうか
結論大丈夫

いいね機能が上手く機能しなくなった。

投稿一覧でなにか一つの投稿にいいねしたあとに
リロードすると、全部の投稿にいいねがつくようになってしまった。

drink.idの受け渡しの方法を工夫したいと思う。

app.vue(投稿一覧)でdrink.idとやったらそれぞれと投稿が
親コンポーネントから子コンポーネントへ値を受け渡すことはできそう。
しかし、user_idが受け渡せない。

index.json.jbuilderに

json.user @user , :id

とかやっても、すでに

index.json.jbuilder

json.array! @drinks do |drink|
  json.id               drink.id
  json.name             drink.name        
  json.explain          drink.explain
  json.price            drink.price
  json.acidity_id       drink.acidity_id
  json.body_id          drink.body_id
  json.processing_id    drink.processing_id
  json.region_id        drink.region_id
  json.region_name      drink.region.name
  json.acidity_name     drink.acidity.name
  json.body_name        drink.body.name
  json.processing_name  drink.processing.name
  json.likes_count      drink.likes_count
  json.user_id          drink.user_id
  json.nickname         drink.user.nickname
  json.image rails_blob_url(drink.image) if drink.image.attached?
end

と書いてるから、できない。
cant add to an arrayとかいうエラーを出された。
そこらへん上手くやってくれよ。jsonsさんよ。。。

drinks/index.html.erbに

<script>
var user = <%= { id: current_user.try(:id) }.to_json.html_safe %>;
</script>

こうやってかけば、drinks#indexにcurrent_userは定義されてあるので、現在ログインしてるユーザーのidをvueに受け渡せる。

これはあまり良くない方法かもしれないが、現在ログインしてるユーザーのidはerbからvueに受け渡して、
投稿のidはapi:index_controller#indexで定義した@drinkから
jbuilderを介して受け渡してもらう
そして、app.vueにlikeButtonが子コンポーネントとして表示されているので、
app.vueに受け渡されたjsonデータを子コンポーネントのlikeButton.vueに受け渡したい

親コンポーネントから子コンポーネントへデータの受け渡し

app.vue

 <likeButton :drinkId=drink.id></likeButton>
likeButton.vue

   props: ["drinkId"],

と記述して、this.drinkIdとかやればアクセスできる。

こうやってやったら、投稿一覧ページからでもいいね機能が機能するようになりました!!

次回は,drink/show.vueをモーダルや、router-viewとかで表示させていきたいとおもいます!!

0
0
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
0
0