所以,我正在构建一个应用程序,其中我有一个用 Rails 编写的后端和一个用 Vue 和 Amplify 编写的客户端。我的数据库是 MySQL,我使用 AWS AppSync 和 GraphQL 作为数据源(指向我的数据库)。
AWS Amplify 有一个框架,允许我使用一个简单的命令根据表名和列生成模式:amplify api add-graphql-datasource
.但是因为我使用的是 Rails 迁移,所以我的数据库使用的是 Rails 约定:带有蛇形列的复数表。
现在,问题在于 GraphQL 模式都很丑陋,并且没有使用正确的约定(类型和输入的单数名称,带有驼峰式的 props)。例子:
我的后端有以下迁移:
class CreatePosts < ActiveRecord::Migration[6.0]
def change
create_table :posts do |t|
t.belongs_to :site, null: false
t.string :title
t.string :url
t.text :body
t.timestamps
end
end
end
为此生成的架构是:
type posts {
id: Int!
site_id: Int!
title: String
url: String
body: String
created_at: AWSDateTime!
updated_at: AWSDateTime!
}
type Query {
getPosts(id: Int!): posts
listPostss: [posts]
// ...
}
schema {
query: Query
// ...
}
更不用说这个了:
input CreatepostsInput {
id: Int!
site_id: Int!
title: String
url: String
body: String
created_at: AWSDateTime!
updated_at: AWSDateTime!
}
所以,AWS Amplify 是新的,它不像 Rails 那样成熟,最重要的是我没有找到任何适配器或转换器来处理客户端中的问题......我希望找到一种在 Rails 上处理它的方法。
我需要能够在不破坏任何东西的情况下完全改变 Rails 约定:迁移、关联、如何管理关联(create_xxx、build_xxx)。
这个应用程序真的很新,所以我可以从头开始重新创建所有迁移。
谢谢
最佳答案
我可以看到一些你可以做的事情:
表:
在您的迁移中,您可以更改表名,但现在您需要使用 self.table_name
让您的模型知道表名是什么。
# migration
class CreatePosts < ActiveRecord::Migration[6.0]
def change
create_table :post do |t| # singular 'post'
...
end
end
end
#model
class Post
self.table_name = "post" # i think you can also use a symbol :post
end
属性:
您需要避免使用遵循 Rails 约定的 Rails 迁移方法,如
t.belongs_to
或 t.references
或 t.timestamps
。# migration
class CreatePosts < ActiveRecord::Migration[6.0]
def change
create_table :post do |t|
# do not use this below
# t.belongs_to :site, null: false
t.bigint :siteId, null: false
t.string :title
t.string :url
t.text :body
# do not use this below
# t.timestamps
t.datetime :createdAt, default: ->{'CURRENT_TIMESTAMP'}
t.datetime :updatedAt, default: ->{'CURRENT_TIMESTAMP'}
end
end
end
关系:
您还需要更新模型中的关系
class Post
belongs_to :site, foreign_key: 'siteId'
end
更多信息可以在 Rails API 中找到。确保检查 documenation for other relationship methods 。
时间戳:
由于时间戳列(
created_at
、 updated_at
)不再是 ActiveRecord 所期望的列,因此您可能需要 override the ActiveRecord::Timestamp
module 才能让它们继续按预期工作。最简单的选择之一是使用以下内容更新您的 ApplicationRecord
或单个模型类:class ApplicationRecord # or class Post
before_create :set_timestamps
before_save :set_timestamps
private
def set_timestamps
self.createdAt = DateTime.current if self.new_record?
self.updatedAt = DateTime.now
end
end
或者取自 https://stackoverflow.com/a/52276865/1845602 的其他选项
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
class << self
private
def timestamp_attributes_for_create
super << 'my_created_at_column'
end
def timestamp_attributes_for_update
super << 'my_updated_at_column'
end
end
end
自动生成的输入 :
我在这里可能错了,但似乎表名被注入(inject)到输入名称中,如
Create<table>Input
,所以如果是这种情况,您可以将表命名为 Post
而不是 post
。input CreatepostsInput {
}
关于ruby-on-rails - 如何覆盖关于复数表和蛇形列的 rails 配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58699571/