@@ -205,6 +205,99 @@ defmodule AshPostgres.MigrationGeneratorTest do
205205 end
206206 end
207207
208+ describe "get_operations_from_snapshots" do
209+ test "explicit fk attribute order does not change create table emission" do
210+ # This also reproduces if a non-identity attribute like :note appears between
211+ # :post_id and the identity key (:title), but this test keeps the minimal case.
212+ defposts do
213+ attributes do
214+ uuid_primary_key ( :id )
215+ end
216+ end
217+
218+ defresource CommentPostIdBeforeTitle , "comments_post_id_before_title" do
219+ attributes do
220+ uuid_primary_key ( :id )
221+ attribute ( :post_id , :uuid , allow_nil?: false , public?: true )
222+ attribute ( :title , :string , public?: true )
223+ end
224+
225+ identities do
226+ identity ( :uniq_title , [ :title ] )
227+ end
228+
229+ relationships do
230+ belongs_to ( :post , Post ) do
231+ source_attribute ( :post_id )
232+ destination_attribute ( :id )
233+ end
234+ end
235+ end
236+
237+ defresource CommentTitleBeforePostId , "comments_title_before_post_id" do
238+ attributes do
239+ uuid_primary_key ( :id )
240+ attribute ( :title , :string , public?: true )
241+ attribute ( :post_id , :uuid , allow_nil?: false , public?: true )
242+ end
243+
244+ identities do
245+ identity ( :uniq_title , [ :title ] )
246+ end
247+
248+ relationships do
249+ belongs_to ( :post , Post ) do
250+ source_attribute ( :post_id )
251+ destination_attribute ( :id )
252+ end
253+ end
254+ end
255+
256+ before_snapshots =
257+ AshPostgres.MigrationGenerator . get_snapshots ( CommentPostIdBeforeTitle , [
258+ Post ,
259+ CommentPostIdBeforeTitle
260+ ] )
261+
262+ after_snapshots =
263+ AshPostgres.MigrationGenerator . get_snapshots ( CommentTitleBeforePostId , [
264+ Post ,
265+ CommentTitleBeforePostId
266+ ] )
267+
268+ assert [ before_snapshot ] = before_snapshots
269+ assert [ after_snapshot ] = after_snapshots
270+ assert Enum . map ( before_snapshot . attributes , & & 1 . source ) == [ :id , :post_id , :title ]
271+ assert Enum . map ( after_snapshot . attributes , & & 1 . source ) == [ :id , :title , :post_id ]
272+
273+ before_ops =
274+ AshPostgres.MigrationGenerator . get_operations_from_snapshots ( [ ] , before_snapshots )
275+
276+ after_ops =
277+ AshPostgres.MigrationGenerator . get_operations_from_snapshots ( [ ] , after_snapshots )
278+
279+ assert Enum . any? (
280+ after_ops ,
281+ & match? (
282+ % AshPostgres.MigrationGenerator.Phase.Create {
283+ table: "comments_title_before_post_id"
284+ } ,
285+ & 1
286+ )
287+ )
288+
289+ assert Enum . any? (
290+ before_ops ,
291+ & match? (
292+ % AshPostgres.MigrationGenerator.Phase.Create {
293+ table: "comments_post_id_before_title"
294+ } ,
295+ & 1
296+ )
297+ )
298+ end
299+ end
300+
208301 describe "creating initial snapshots" do
209302 setup % { snapshot_path: snapshot_path , migration_path: migration_path } do
210303 :ok
0 commit comments