yuuto222
@yuuto222 (hayasaki yuuto)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

既に同じ車がレンタルされている場合の処理をしたい

前提

Ruby on railsを用いて、車のレンタル機能を開発しております。
レンタル画面(car_logs/take)、返却画面(car_logs/return)、車使用履歴画面(car_logs)がある。

db/schema.rb

create_table "car_logs", comment: "車使用履歴", force: :cascade do |t|
    t.bigint "car_id", comment: "車id"
  t.bigint "line_id", comment: "ラインid"
    t.datetime "take_datetime", comment: "レンタル日時"
    t.bigint "take_user_id", comment: "レンタル日時"
    t.datetime "return_datetime", comment: "返却日時"
    t.bigint "return_user_id", comment: "返却日時"
    t.integer "before_weight", comment: "使用前重量"
    t.integer "after_weight", comment: "使用後重量"
    t.integer "used_weight", comment: "使用量"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["car_id"], name: "index_paintcan_logs_on_paintcan_id"
  end

create_table "cars", comment: "車", force: :cascade do |t|
    t.datetime "arrival_datetime", comment: "入荷日時"
    t.string "product_number", comment: "品番"
    t.integer "weight", comment: "重量"
    t.bigint "location_id", comment: "ロケーションid"
    t.bigint "create_user_id", comment: "作成者id"
    t.bigint "update_user_id", comment: "更新者id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

実現したいこと

レンタル画面で持ち出し登録した際に、既に同じ車が別のラインでレンタルされている場合は、自動で返却処理がなされるようにしたい
そのために車使用履歴から既に同じ自転車が別のラインでレンタルされている場合という条件式を記述したい

発生している問題・エラーメッセージ

既に同じ車が別のラインでレンタルされていることを検知できない

該当のソースコード

app/controllers/car_logs/takes_controller.rb

def create
    car_logs = []

    ActiveRecord::Base.transaction do

      car_logs_params.each do |car_log_params|
        car_log = CarLog.new(car_log_params)
        car_log.take_datetime = params[:take_datetime] || Time.current
        car_log.take_user_id = params[:take_user_id]
        car_log.line_id = params[:line_id]
        car_log.created_by(current_user)
      end

      raise ActiveRecord::Rollback unless success
    end

  end

app/views/car_logs/takes/show.html.slim

//入力フォーム 2つのVue.jsで定義
#app(v-cloak)

  = form_with(url: car_logs_take_path) do |f|
    car-logs-form(
      v-model='carLogs'
      now=Time.current.iso8601[0..18]
      :current-user='currentUser'
      :last-line='line'
      :production-schedule='productionSchedule'
    )
    = f.submit //持ち出し登録ボタン ここをクリックしたときの処理を追加したい

= javascript_packs_with_chunks_tag 'car_logs/takes/show'

app/javascript/components/car_logs/takes/Form.vue

<template lang='pug'>
div
  .d-flex.justify-content-between
    .form-group
      .form-inline
        .form-group
          label ライン
          LineSelect(
            name='line_id'
            v-model='lineId'
            :line.sync='line'
            required
          )
        .form-group
          label レンタル者
          UserSelect(
            name='take_user_id'
            v-model='takeUserId'
            :user.sync='takeUser'
            required
          )
    div
      button.btn.btn-info(type='button' @click='add(null)') 追加

  .table-sticky.max-vh-60(ref='recordsContainer')
    table.table.table-form.table-striped.table-bordered
      thead
        tr
          th RFID
          th 品番
          th ロット番号
          th 重量(g)
          th 製品
          th
      tbody
        template(v-for='(record, index) in records')
          CarLogRow(
            ref='detailRows'
            :name='`car_logs[${index}]`'
            :key='record.key'
            :record='records[index]'
            :date='datetime'
            @remove='remove'
            @insert='insert(index)'
          )
</template>

<script>
import {v4 as uuid} from 'uuid'
import CarLogRow from './CarLogRow'
import LineSelect from '~/components/LineSelect'
import UserSelect from '~/components/UserSelect'

const newRecord = () => {
  return {
    key: uuid(),
    beforeWeight: null,
    product: null,
    paintNumber: null,
  }
}

export default {
  components: {
    carLogRow,
  },
  model: {
    prop: 'records',
  },
  props: {
    records: {
      type: Array,
    },
    now: {
      type: String,
    },
    currentUser: {
      type: Object,
    },
    lastLine: {
      type: Object,
    },
    productionSchedule: {
      type: Object
    },
  },
  data(){
    return {
      datetime: this.now,
      lineId: this.lastLine?.id,
      line: this.lastLine,
      takeUserId: this.currentUser.id,
      takeUser: this.currentUser,
      bPaint: this.production.bPaint,
      tPaint: this.production.tPaint,
      Number: this.production.Number,
    }
  },
  async mounted(){
    this.records.forEach((record) => {
      record.key = uuid()
    })
    if(this.records.length === 0 ){
      if(this.bPaint == null && this.tPaint == null){
        this.add(null)
      }
      else{
        if (this.bPaint != null){
          this.add(this.bPaint)
        }
        if (this.tPaint != null){
          this.add(this.tPaint)
        }
      }
    }

    await this.$nextTick()
    this.$refs.detailRows[0].focus()
  },
  methods: {
    async add(paint){
      let newRecort = newRecord()
      newRecort = {product: this.Number, paint: paint}
      this.records.push(newRecort)
      await this.$nextTick()
      scrollToBottom(this.$refs.recordsContainer)
    },
    async insert(index){
      arrayInsert(this.records, newRecord(), index + 1)
      await this.$nextTick()
      this.$refs.detailRows.at(-1).focus()
    },
    remove(record){
      arrayDelete(this.records, record)
      if(this.records.length === 0){
        this.add(null)
      }
    },
  },
}
</script>

app/javascript/components/car_logs/takes/CarLogRow.vue

<template lang="pug">
tr(@keypress.stop='onKeypress')
  td
    input.form-control(
      ref='defaultFocusInput'
      type='text'
      v-model='record.rfid'
      @change='onRfidChange'
      required
    )
    input(
      type='hidden'
      v-model='car.id'
      :name='`${name}[car_id]`'
    )
  td {{car.Number}}
  td {{car.lotNumber}}
  td
    input.form-control(
      type='number'
      v-model.number='record.beforeWeight'
      :name='`${name}[before_weight]`'
      step='any'
      required
    )
  td
    TextField.w-100(
      v-model='record.product'
      :name='`${name}[product]`'
      :autocomplete='products'
      @focus='onProductFocus'
    )
  td.text-nowrap
    button.btn.btn-warning(type='button' @click='remove(record)') 削除
</template>

<script>
import axios from "axios";
import insertCommand from "~/lib/event/insertCommand";

function checkProductNumber(currentPaintNumber, loadedPaintNumber) {
  if (currentPaintNumber == null || currentPaintNumber === "") {
    return true;
  } else {
    if (currentPaintNumber !== loadedPaintNumber) {
      const ask = window.confirm(
        `品番が一致しません。`
      );
      return ask;
    } else {
      return true;
    }
  }
}

export default {
  model: {
    prop: "record"
  },
  props: {
    name: {
      type: String
    },
    record: {
      type: Object
    },
    date: {
      type: String
    },
    currentRfId: {
      type: Number
    }
  },
  data() {
    return {
      car: {},
      products: []
    };
  },
  async mounted() {
    this.car = { Number: this.record.paint, lotNumber: "" };
  },
  methods: {
    focus() {
      this.$refs.defaultFocusInput.focus();
    },
    onKeypress(e) {
      if (insertCommand(e)) {
        this.$emit("insert");
      }
    },
    remove(record) {
      this.$emit("remove", record);
    },
    async onRfidChange(e) {
      const input = e.target;
      const id = this.record.rfid;
      try {
        const result = await axios.get(`/api/web/cars/${id}`);
        console.log(result.data);
        if (
          checkNumber(
            this.car.Number,
            result.data.Number
          )
        ) {
          this.car = result.data;
          input.setCustomValidity("");
          this.currentRfId = id; 
        } else {
          this.record.rfid = this.currentRfId;
        }
      } catch (e) {
        this.car = {};
        input.setCustomValidity("");
      }
    },
    async onProductFocus(e) {
      this.products = [];

      const params = {
        date: this.date
      };
      const result = await axios.get("/api/web/productions", {
        params
      });
      console.log(result);

      this.products = result.data.map(
        it => `${it.productNumber} ${it.productName}`
      );
    }
  }
};
</script>

試したこと

持ち出し登録した際に、既に同じものが別のラインで持ち出されている場合であることを検知するために以下の記述をしたが、登録しようとしているものと同じcar_idをまず、検知できていないため、何か気づくことがあれば教えて頂けると幸いです。
app/controllers/car_logs/takes_controller.rb

def create
省略
    car_ids = CarLog.find(&:car_id)
    take_datetimes =CarLog.find(&:take_datetime)
    return_datetimes = CarLog.find(&:return_datetime)
    line_ids = CarLog.find(&:line_id)

    if car_ids.present?
      logger.debug("登録しようとしているものと同じcar_idがある")
      if take_datetimes.present? && return_datetimes.nil?
        logger.debug("レンタル日時のみあって、返却日時がないデータは存在する")
        if line_ids.present?
          logger.debug("登録しようとしているラインと異なる")
          logger.debug("返却処理を行い、再度登録する")
        end
      end
    else
      logger.debug("通常通り登録する")
    end
end

補足情報(FW/ツールのバージョンなど)

バージョン情報
Rails 6.1.4.7
ruby 3.1.2

0

No Answers yet.

Your answer might help someone💌