ruby-on-rails - 如何覆盖关于复数表和蛇形列的 rails 配置

标签 ruby-on-rails amazon-web-services graphql aws-amplify

所以,我正在构建一个应用程序,其中我有一个用 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_tot.referencest.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_atupdated_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/

相关文章:

api - 在哪里可以获取亚马逊类别列表 API

python - 如何使用 gql 客户端在 GraphqQL 查询中声明变量?

rest - REST 比 GraphQL 更适合的项目?

ruby-on-rails - ruby rails : Validate HTML and CSS on file upload

amazon-web-services - 如何通过 cloudformation 公开访问 aws aurora serverless v2

python - Django collectstatic 命令在 AWS Elastic Beanstalk Amazon Linux 2 Python 3 平台中失败

node.js - 错误 : Cannot find module 'graphql/validation/rules/PossibleTypeExtensions'

javascript - 如何将变量从 javascript (coffeescript) 传递到 Rails Controller ?

ruby-on-rails - 创建一个已经完成入职的测试条帐户?

ruby-on-rails - 如何仅针对某些区域设置而不是全部区域设置启用 Rails i18n 后备?