Создан Ожидается создан (Time | Nil), но получил (Float64 | String) - PullRequest
2 голосов
/ 03 мая 2020

Я новичок в этой янтарной среде, Crystal Lang и объектно-ориентированном программировании в целом. Я следовал учебным пособиям и пытался создать простую форму с использованием этой платформы

amber g scaffold item name:string path:string type:string size:float created:date

. Я вижу, что этот класс был создан в папке моделей

class Item < Granite::Base
  connection pg
  table items

  column id : Int64, primary: true
  column name : String?
  column path : String?
  column type : String?
  column size : Float64?
  column created : Time?
  timestamps

end

Когда я запустил приложение и устал вставлять новый элемент, я получил эту ошибку

Создано Ожидается, что создано (Time | Nil), но получил (Float64 | String).

Это код формы .slang

== form(action: "/items/#{item.id.to_s}", method: item.id ? :patch : :post) do
  == csrf_tag
  .form-group
    == text_field(name: "name", value: item.name, placeholder: "Name", class: "form-control")
  .form-group
    == text_field(name: "path", value: item.path, placeholder: "Path", class: "form-control")
  .form-group
    == text_field(name: "type", value: item.type, placeholder: "Type", class: "form-control")
  .form-group
    == text_field(name: "size", value: item.size, placeholder: "Size", class: "form-control")
  .form-group
    == text_field(name: "created", value: item.created, placeholder: "Created", class: "form-control")
    == submit("Submit", class: "btn btn-success btn-sm")
  == link_to("Back", "/items", class: "btn btn-light btn-sm")

Я предполагаю, что при вводе значения, такого как 2020-01-01 00:01:00, это обрабатывается как строка, но мне нужно, чтобы это было преобразовано в Тип времени. Я предполагаю, что это должно произойти с соответствующим файлом контроллера, но я не знаю, как это сделать.

Это код, который выполняется при попытке создать новый элемент.

  def create
    item = Item.new item_params.validate!
    if item.save
      redirect_to action: :index, flash: {"success" => "Item has been created."}
    else
      flash[:danger] = "Could not create Item!"
      render "new.slang"
    end
  end

спасибо, гуррурин

Ответы [ 2 ]

0 голосов
/ 08 мая 2020

Вам не нужны эти дополнительные методы установки, они уже определены макросом column . Вам не нужен дополнительный созданный столбец, уже есть create_at и updated_at столбцы, созданные макросом timestamps , и они обновляются для вас при создании новой записи и сохранении измененной записи.

Кроме этого, если вы ДЕЙСТВИТЕЛЬНО создали столбец с типом времени, вы бы сделали

item.created = Time.parse(params[:created],"%Y-%m-%d %H:%M:%S %z", Time::Location::UTC)

, а Granite сделает правильное преобразование для каждого механизма базы данных при сохранении и чтении записи.

0 голосов
/ 07 мая 2020

Я смог заставить это работать, создав несколько новых функций

class Item < Granite::Base
...
      def set_id (id : Int64)
        @id = id
      end
      def set_name (name : String)
        @name = name
      end
      def set_filetype (filetype : String)
        @filetype = filetype
      end
      def set_filesize (filesize : Float64)
        @filesize = filesize
      end
      def set_filepath (filepath : String)
        @filepath = filepath
      end
      def set_created (cr : Time)
        @created = cr
      end

, а затем использовал их после инициализации пустого элемента

item = Item.new
item.set_name(params[:name])
item.set_filetype(params[:filetype])
item.set_filesize(params[:filesize].to_f64)
item.set_filepath(params[:filepath])
item.set_created(Time.parse(params[:created],"%Y-%m-%d %H:%M:%S %z", Time::Location::UTC))

, хотя я не думаю, что это лучшее решение здесь. Так как этот объект parmas хранит все в виде строк, я подозреваю, что при инициализации нового элемента строка типа «2020-01-01 00:01:00 UT C» не конвертируется в соответствующий тип времени. Другие типы, такие как Int или Float, работают нормально без isseus.

item = Item.new item_params.validate!
...