Cómo anular las configuraciones de rieles con respecto a tablas pluralizadas y columnas con carcasa de serpiente

8

Entonces, estoy construyendo una aplicación donde tengo un backend escrito en Rails y un cliente escrito en Vue con Amplify. Mi base de datos es MySQL y estoy usando AWS AppSync con GraphQL como fuente de datos (apuntando a mi base de datos).

El AWS Amplify tiene un marco que me permite generar los esquemas basados en los nombres de tablas y columnas con un comando simple: amplify api add-graphql-datasource. Pero debido a que estoy usando migraciones de rails, mi base de datos está usando convenciones de Rails: tablas pluralizadas con columnas en forma de serpiente.

Ahora, el problema con eso es que los esquemas de GraphQL son todos feos y no usan las convenciones correctas (nombres singulares para los tipos y entradas, con accesorios en camello). Ejemplo:

Mi backend tiene la siguiente migración:

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

Y el esquema generado para esto es:

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

Sin mencionar esto:

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

Entonces, AWS Amplify es nuevo, no es maduro como Rails, y además no encontré ningún adaptador o transformador para manejar el problema en el cliente ... mi esperanza es encontrar una manera de manejarlo en Rails.

Necesito poder cambiar por completo las convenciones de Rails sin romper nada: migraciones, asociaciones, cómo administrar asociaciones (create_xxx, build_xxx).

Esta aplicación es realmente nueva, por lo que puedo recrear todas las migraciones desde cero.

Gracias

Amanda Ferrari
fuente

Respuestas:

1

Puedo ver algunas cosas que puedes hacer:

Mesas:

En su migración, puede cambiar el nombre de la tabla, pero ahora necesita que su modelo sepa cuál es el nombre de la tabla 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:

Debe evitar el uso de métodos de migración de Rails que sigan las convenciones de Rails como t.belongs_toor t.referenceso 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

Relaciones:

También necesita actualizar sus relaciones en sus modelos

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

Se puede encontrar más información en la API de Rails . Asegúrese de revisar la documentación para otros métodos de relación .

Marcas de tiempo:

Dado que las columnas de marcas de tiempo ( created_at, updated_at) ya no son las esperadas por ActiveRecord, es posible que deba anular el ActiveRecord::Timestampmódulo para que continúen funcionando como era de esperar. Una de las opciones más fáciles es actualizar su ApplicationRecordclase de modelo o una sola con lo siguiente:

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

O esta otra opción tomada de 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 generadas automáticamente :

Podría estar equivocado aquí, pero parece que el nombre de la tabla se está inyectando en el nombre de entrada Create<table>Input, por lo que, si ese es el caso, puede nombrar su tabla en Postlugar de post.

input CreatepostsInput {
}
Edgar Ortega
fuente