Cambiare ordine migrazioni


#1

Utilizzo InstantRails 2.0 e avrei l’esigenza di cambiare l’ordine di
esecuzione delle migrazioni… In particolare devo creare una migrazione
che si inserisca in un certo punto tra quelle che ho già fatto.
Qualcuno sa come si fa ??

Altra cosa: come faccio a impostare (in una migrazione) un campo foreign
key in modo che contenga il riferimento al record di un’altra tabella
(ench’esso creato tramite migrazione) ??

Grazie per l’attenzione.


#2

le migrations vengono eseguite in ordine, di solito incominciano tutte
con un numero, può essere la data(meglio giusto per avere qualche info
in piu) ho un semplice numero di sequenza. per il roolback fa la cosa
opposta.

001_create…
002_create…
007_create…

in questo caso saranno eseguite nel seguente ordine, 001 > 002 > 007
ps: non importa che ci sia un buco fra 2 e 7 rails le ordina e le
esegue.


#3

Andrea C. wrote:

le migrations vengono eseguite in ordine, di solito incominciano tutte
con un numero, pu� essere la data(meglio giusto per avere qualche info
in piu) ho un semplice numero di sequenza. per il roolback fa la cosa
opposta.

001_create…
002_create…
007_create…

in questo caso saranno eseguite nel seguente ordine, 001 > 002 > 007
ps: non importa che ci sia un buco fra 2 e 7 rails le ordina e le
esegue.

Mi sa che non ci siamo capiti… Io ho le migrazioni 001 002 003 004
005.
Diciamo che voglio aggiungere una nuova migrazione tra la 002 e la 003.

Come dovrei fare ??


#4

devi cambiare i numerini :]

se usi le date è meglio anche per questi casi, qui usiamo data e ora
tipo 20082710090001
penso che cambiando il prefisso non dovresti aver nessun problema,
prova :]


#5

che io sappia non c’è modo diretto perché la logica delle migration
è proprio quella di modifiche progressive utili in un ambiente giÃ
rilasciato.
Per quanto ne so io, devi modificare le tabelle che hai già creato
all’interno della nuova migrazione. in modo tale da mantenere la
progressione

per esempio questa migrazione fa delle modifiche su una tabella giÃ
esistente (gestita se non ricordo male con attachemnt_fu ma non credo
che importi) e dà un valore a un campo eseguendo del codice RoR

class Asset < ActiveRecord::Base; end
class MakeAssetsAttachable < ActiveRecord::Migration
def self.up
add_column :assets, :attachable_id, :integer
add_column :assets, :attachable_type, :string, :limit => 12
add_column :assets, :created_at, :datetime
Asset.find(:all).each do |asset|
asset.attachable_id = asset.id
asset.attachable_type = ‘mytype’
asset.save
end
remove_column :assets, :content_id
add_index :assets, [:attachable_id, :attachable_type]
end

def self.down
remove_index :assets, [:attachable_id, :attachable_type]
add_column :assets, :content_id, :integer
Asset.find(:all).each do |asset|
asset.auction_id = asset.id
asset.save
end
remove_column :assets, :attachable_id
remove_column :assets, :attachable_type
remove_column :assets, :created_at
end
end

Naturalmente se per te non è un problema puoi cambiare la numerazione
delle migration ma devi ripartire dalla migration 0 oppure puoi
farle per il futuro divise per 10 o 100 10_m1 20_m2 eccetera e
metterci in mezzo quello che vuoi( questa cosa mi è venuta in mente
solo adesso)

mi spiace anche dover confessare :slight_smile: che io le foreign key le ho sempre
aggiunte in questo modo
execute ‘ALTER TABLE TableA ADD CONSTRAINT fk_tableA_TableB
FOREIGN KEY (myfk) REFERENCES tableb (tablebfield) ON DELETE
CASCADE ON UPDATE CASCADE;’

Il giorno 19/nov/08, alle ore 18:48, Davide S. ha scritto:


#6

Ma quindi non ci sono problemi a ri-numerare manualmente i filename
delle migrazioni ?? Mi sembrava di aver letto da qualche parte che Rails
usa una sua tabella di database per tenere traccia dell’ordine delle
migrazioni…

Le migrazioni quindi sono eseguite unicamente in base al loro filename e
possono quindi essere gestite manualmente a piacimento ??


#7

C’è una tabella schema_info con un solo campo version. Se
aggiungi una migrazione devi incrementare di uno anche il valore del
campo altrimenti Rails penserà di essere indietro di una migrazione.

Perdonami ma questa parte non l’ho proprio capita…

Cosa dovrei fare, nel dettaglio ??


#8

Davide S. wrote:

Ma quindi non ci sono problemi a ri-numerare manualmente i filename
delle migrazioni ?? Mi sembrava di aver letto da qualche parte che Rails
usa una sua tabella di database per tenere traccia dell’ordine delle
migrazioni…

Le migrazioni quindi sono eseguite unicamente in base al loro filename e
possono quindi essere gestite manualmente a piacimento ??

Ricordi bene. C’è una tabella schema_info con un solo campo version. Se
aggiungi una migrazione devi incrementare di uno anche il valore del
campo altrimenti Rails penserà di essere indietro di una migrazione.

Per il resto puoi fare tutto quel che vuoi, basta fare attenzione ad
inserire correttamente la nuova migrazione nella sequenza dei metodi up
e down di quelle esistenti.

Paolo


#9

2008/11/19 Davide S. removed_email_address@domain.invalid:

C’è una tabella schema_info con un solo campo version. Se
aggiungi una migrazione devi incrementare di uno anche il valore del
campo altrimenti Rails penserà di essere indietro di una migrazione.

Perdonami ma questa parte non l’ho proprio capita…

Cosa dovrei fare, nel dettaglio ??

la questione vale solo per un db già parzialmente o totalmente
migrato: diciamo che hai 4 migrazioni, chiamate 001_…, 002_…,
003_…, 004_…

sul tuo pc hai probabilmente un db già migrato allo stato attuale.

ora, decidi di aggiungere una migrazione tra la 2 e la tre. per farlo,
rinomini 004 in 005 e 003 in 004, così puoi creare un nuovo 004. se
ora, però, esegui rake db:migrate, lui vedrà che in tutto ci sono 5
migrazioni, sul db c’è scritto che ne ha fatte 4 e quindi cercherà di
effettuare l’ultima migrazione, cioè la 005 (la quale, probabilmente,
non funzionerà, visto che l’hai già fatta).

quindi, se vuoi che il db che hai risulti aggiornato, devi modificare
il campo version in schema_info, incrementandolo.

ripeto, ciò vale solo per i db già presenti; se domani installi la tua
applicazione su un altro computer e fai rake db:migrate, va tutto
bene.


#10

Capisco, comunque a me il problema non si pone perchè torno sempre alla
versione 0 delle migrazioni, prima di fare delle modifiche…

Per quanto riguarda la seconda cosa invece mi potete aiutare ??

migrazione 003 —> crea la tabella USERPERMISSIONS (id/type)
e crea 3 record di qualla tabella

                (es. id=1 type=normal)
                (es. id=2 type=admin)
                (es. id=3 type=super_admin)

migrazione 004 —> crea la tabella ADMINS
(id/name/password/userpermission_id)
e crea 1 record di quella tabella

                (es. id=1 name=admin password=*** 

usermission_id=???)

Io vorrei collegare la foreign key di quest’ultimo record direttamente a
quel record di USERPERMISSIONS che ha valore “super_admin” nel campo
“type”.

E’ possibile farlo ??


#11

Se sei sicuro che il record a cui vuoi legarti ha id=3;

class Admin < ActiveRecord::Base; end
class CreateTest < ActiveRecord::Migration
def self.up
create_table :admins do |t|
t.string :name
t.string :password
t.integer :userpermission_id

end
Admin.create(:name => ‘admin’, :password => ‘***’,
:userpermission_id => 3)
end

def self.down
drop_table :admins
end
end


#12

No che non sono sicuro, però se faccio una query non mi funziona… :confused:


#13

Davide S. wrote:

No che non sono sicuro, però se faccio una query non mi funziona… :confused:

Prova allora a definire nella migrazione, accanto alla
class Admin < ActiveRecord::Base; end
la
class Userpermission < ActiveRecord::Base; end

e usare
Userpermission.find_by_type(‘super_admin’)


#14

Claudio Petasecca D. wrote:

Davide S. wrote:

No che non sono sicuro, però se faccio una query non mi funziona… :confused:

Prova allora a definire nella migrazione, accanto alla
class Admin < ActiveRecord::Base; end
la
class Userpermission < ActiveRecord::Base; end

e usare
Userpermission.find_by_type(‘super_admin’)

Cioè ? 2 classi dentro alla stessa migrazione ??

Userpermission.find_by_type(‘super_admin’) l’ho già usato, ma è proprio
quello che non funziona.


#15

Tre classi dentro la stessa migrazione: due classi ActiveRecord e una
Migration.

Cosa significa ?

Userpermission.find_by_type(‘super_admin’) l’ho già usato, ma è proprio
quello che non funziona.

Non lo so, mi dice che il campo type è nil…


#16

Davide S. wrote:

Cioè ? 2 classi dentro alla stessa migrazione ??

Tre classi dentro la stessa migrazione: due classi ActiveRecord e una
Migration.

Userpermission.find_by_type(‘super_admin’) l’ho già usato, ma è proprio
quello che non funziona.

Percha’ non ti funziona?


#17

Davide S. wrote:

Capisco, comunque a me il problema non si pone perchè torno sempre alla
versione 0 delle migrazioni, prima di fare delle modifiche…

Per quanto riguarda la seconda cosa invece mi potete aiutare ??

migrazione 003 —> crea la tabella USERPERMISSIONS (id/type)
e crea 3 record di qualla tabella

                (es. id=1 type=normal)
                (es. id=2 type=admin)
                (es. id=3 type=super_admin)

type è una parola riservata (per l’STI).
prova ad usare qualcos’altro… ad esempio “kind”

migrazione 004 —> crea la tabella ADMINS
(id/name/password/userpermission_id)
e crea 1 record di quella tabella

                (es. id=1 name=admin password=*** 

usermission_id=???)

Io vorrei collegare la foreign key di quest’ultimo record direttamente a
quel record di USERPERMISSIONS che ha valore “super_admin” nel campo
“type”.

E’ possibile farlo ??

se usi “type” devi usare l’STI, ma in questo caso ti sarebbe poco utile
(avresti una classe per ogni tipo)
cambiando il nome del campo tutto dovrebbe tornare a funzionare.

Spero di esserti stato utile

Ciao
Duilio R.


#18

Ho provato l’accesso diretto su una mia tabella polimorfica (cioè che ha
i due campi :id e :type), dichiarata on-the-fly (quindi senza
polimorfismo, come semplice classe class Yyy < ActiveRecord::Base; end )
e la find_by_type sembra funzionare correttamente.

Comunque resta il fatto, come suggerito da Duilio, che il campo :type
deve essere lasciato per quello scopo.