So überschreiben Sie Schienenkonfigurationen in Bezug auf pluralisierte Tabellen und Säulen mit Schlangengehäuse

8

Also baue ich eine App, in der ich ein Backend in Rails und einen Client in Vue mit Amplify geschrieben habe. Meine Datenbank ist MySQL und ich verwende AWS AppSync mit GraphQL als Datenquelle (zeigt auf meine Datenbank).

AWS Amplify verfügt über ein Framework, mit dem ich die Schemas basierend auf den Tabellennamen und Spalten mit einem einfachen Befehl generieren kann: amplify api add-graphql-datasource . Da ich jedoch Rails-Migrationen verwende, verwendet meine Datenbank Rails-Konventionen: pluralisierte Tabellen mit Spalten mit Schlangengehäuse.

Das Problem dabei ist, dass die GraphQL-Schemata alle hässlich sind und nicht die richtigen Konventionen verwenden (singuläre Namen für die Typen und Eingaben mit Requisiten im Kamelgehäuse). Beispiel:

Mein Backend hat folgende Migration:

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

Und das dafür generierte Schema lautet:

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

Ganz zu schweigen davon:

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

AWS Amplify ist also neu, es ist nicht ausgereift wie Rails, und außerdem habe ich keinen Adapter oder Transformator gefunden, um das Problem im Client zu lösen. Ich hoffe, einen Weg zu finden, um es auf Rails zu lösen.

Ich muss in der Lage sein, die Rails-Konventionen vollständig zu ändern, ohne etwas zu beschädigen: Migrationen, Assoziationen, Verwalten von Assoziationen (create_xxx, build_xxx).

Diese App ist wirklich neu, so dass ich alle Migrationen von Grund auf neu erstellen kann.

Vielen Dank

Amanda Ferrari
quelle

Antworten:

1

Ich kann einige Dinge sehen, die Sie tun können:

Tabellen:

Während Ihrer Migration können Sie den Tabellennamen ändern. Jetzt müssen Sie Ihrem Modell mitteilen, wie der Tabellenname lautet 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

Attribute:

Sie müssen die Verwendung von Rails-Migrationsmethoden vermeiden, die den Rails-Konventionen wie t.belongs_tooder t.referencesoder entsprechen 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

Beziehungen:

Sie müssen auch Ihre Beziehungen in Ihren Modellen aktualisieren

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

Weitere Informationen finden Sie in der Rails-API . Stellen Sie sicher, dass Sie die Dokumentation auf andere Beziehungsmethoden überprüfen .

Zeitstempel:

Da die Zeitstempelspalten ( created_at, updated_at) nicht mehr von ActiveRecord erwartet werden, müssen Sie möglicherweise das ActiveRecord::TimestampModul überschreiben , damit sie wie erwartet weiterarbeiten. Eine der einfachsten Möglichkeiten besteht darin, Ihre ApplicationRecordoder eine einzelne Modellklasse wie folgt zu aktualisieren :

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

Oder diese andere Option von 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

Automatisch generierte Eingaben :

Ich könnte mich hier irren, aber es scheint, dass der Tabellenname wie folgt in den Eingabenamen eingefügt Create<table>Inputwird. Wenn dies der Fall ist, können Sie Ihre Tabelle Poststattdessen benennen post.

input CreatepostsInput {
}
Edgar Ortega
quelle