Como substituir configurações de trilhos em relação a tabelas pluralizadas e colunas revestidas de serpentes

8

Então, estou criando um aplicativo no qual tenho um back-end escrito em Rails e um cliente escrito em Vue com Amplify. Meu banco de dados é MySQL e estou usando o AWS AppSync com um GraphQL como fonte de dados (apontando para o meu banco de dados).

O AWS Amplify tem um quadro que me permite gerar os esquemas baseados nos nomes de tabelas e colunas com um comando simples: amplify api add-graphql-datasource. Mas, como estou usando migrações do Rails, meu banco de dados está usando as convenções do Rails: tabelas pluralizadas com colunas revestidas por serpentes.

Agora, o problema disso é que os esquemas do GraphQL são feios e não usam as convenções corretas (nomes singulares para os tipos e entradas, com adereços revestidos com camelo). Exemplo:

Meu back-end possui a seguinte migração:

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

E o esquema gerado para isso é:

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
  // ...
}

Sem mencionar isso:

input CreatepostsInput {
  id: Int!
  site_id: Int!
  title: String
  url: String
  body: String
  created_at: AWSDateTime!
  updated_at: AWSDateTime!
}

Portanto, o AWS Amplify é novo, não é maduro como Rails e, além disso, não encontrei nenhum adaptador ou transformador para lidar com o problema no cliente ... minha esperança é encontrar uma maneira de lidar com isso no Rails.

Eu preciso ser capaz de mudar completamente as convenções do Rails sem quebrar nada: migrações, associações, como gerenciar associações (create_xxx, build_xxx).

Este aplicativo é realmente novo, para que eu possa recriar todas as migrações do zero.

obrigado

Amanda Ferrari
fonte

Respostas:

1

Eu posso ver algumas coisas que você pode fazer:

Tabelas:

Na sua migração, você pode alterar o nome da tabela, mas agora precisa informar ao seu modelo qual é o nome da tabela 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

Atributos:

Você precisa evitar o uso de métodos de migração do Rails que seguem as convenções do Rails, como t.belongs_toou t.referencesou 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

Relacionamentos:

Você também precisa atualizar seus relacionamentos em seus modelos

class Post
  belongs_to :site, foreign_key: 'siteId'
end

Mais informações podem ser encontradas na API do Rails . Verifique a documentação para outros métodos de relacionamento .

Data e hora:

Como as colunas de registro de data e hora ( created_at, updated_at) não são mais as esperadas pelo ActiveRecord, talvez seja necessário substituir o ActiveRecord::Timestampmódulo para que elas continuem funcionando como seria de esperar. Uma das opções mais fáceis é atualizar sua ApplicationRecordclasse de modelo ou única com o seguinte:

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

Ou essa outra opção, obtida em 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

Entradas geradas automaticamente :

Eu posso estar errado aqui, mas parece que o nome da tabela está sendo injetado no nome da entrada como Create<table>Input, portanto, se for esse o caso, você pode nomear sua tabela em Postvez de post.

input CreatepostsInput {
}
Edgar Ortega
fonte