我是这个amber框架、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|字符串(。
这是.俚语形式的代码
== 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这样的值时,它会作为字符串处理,但我需要将其转换为Time类型。我认为这需要在相关的控制器文件上发生,但我不知道如何做到这一点。
这是当我尝试创建一个新项目时执行的代码。
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
谢谢,gurrurin
我能够通过创建一些新的功能使thsi工作
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 UTC"这样的字符串不会转换为合适的时间类型。其他类型,如Int或Float,似乎在没有isseus的情况下工作得很好。
item = Item.new item_params.validate!
您不需要任何额外的setter方法,它们已经由列宏定义。您不需要额外的创建列,时间戳宏已经创建了created_at和updated_at,它们在创建新记录和保存修改后的记录时会为您更新。
除此之外,如果你确实创建了一个时间类型的列,你会进行
item.created = Time.parse(params[:created],"%Y-%m-%d %H:%M:%S %z", Time::Location::UTC)
Granite将在您保存和读取记录时为每个数据库引擎进行正确的转换。