Vraag Hoe de primaire ID van een record in Rails wijzigen?


rails console
u = User.find (9)
u.id = 7 # Er is geen ander record met id 7
u.save
=> waar
User.all

Het ID is niet veranderd.

Hoe de primaire ID te wijzigen? Waarom voorkomt deze actie?

Werken in Rails 3.0.7 en PostgreSQL.

BEWERK: Omdat er goede redenen zijn om dit niet te doen, zal ik uitleggen waarom en hopelijk is dit een goede reden.

We doen Usability Testing op Staging, dus ik wil dat het eruit ziet als de Productie om het voor iedereen gemakkelijk te maken. Ik wil geen verwarring of fouten creëren in het Usability Testing-proces door een aantal dingen in één volgorde op Staging en in een andere volgorde op Productie te plaatsen. Ik heb slechts één PK-id in Staging DB gewijzigd.

Doe dit niet op uw productie DB!


18
2017-11-28 20:04


oorsprong


antwoorden:


Ik weet niet zeker waarom het die actie voorkomt, maar het voorkomt het zeker.

U kunt dit omzeilen met behulp van de update_all-methode voor de gebruiker.

User.where(id: 7).update_all(id: 9)

Maar als het mogelijk is, moet je dit echt vermijden.


23
2017-11-28 20:07



Voor mij werkte:

User.find(9).update_column(:id, 7)

8
2017-07-02 09:37



@Jason wees op een zeer geldig punt. Ik ben het helemaal met hem eens. Maar u kunt uw redenen hebben en ik raad u aan opnieuw te overwegen wat u probeert te doen.

Om je vraag te beantwoorden:

ID-kolommen zijn standaard beveiligd voor massatoewijzing en kunnen niet handmatig worden ingesteld. U kunt dit gedrag echter overschrijven door een methode te definiëren:

def self.attributes_protected_by_default
  [] # ["id", ..other]
end

Hiermee kunt u ID's handmatig toewijzen.


4
2017-11-28 20:15



Kun je uitleggen wat jouw use-case is? Waarom wil je de ID wijzigen? Wat probeer je er echt mee te bereiken?

Over het algemeen het is een slecht idee om dit te doen, en Rails zal dit je niet gemakkelijk laten doen, omdat het je gegevensintegriteit zal schenden!

Dit is waarom: Wanneer u een relationele database (zoals PostgreSQL) eronder gebruikt, zult u relaties hebben tussen uw modellen, wat betekent dat u de model-ID's als referentie in andere gerelateerde modellen zult gebruiken ... wat betekent dat als u de ID van een item wijzigt , al die verwijzingen naar die invoer zullen oud worden en je database corrumperen ..

Ik zou sterk aanbevelen om uw vereisten opnieuw te analyseren en een andere manier te vinden om te bereiken wat u moet doen (zonder de ID's te wijzigen)


4
2017-11-28 20:17



Een andere methode (hoewel het geen pure Rails is) is om een ​​nieuwe kolom te maken en deze te vullen met je nieuwe ID's.

Gebruik vervolgens DB-beheersoftware (geen Rails) en verwijder het kenmerk Primaire sleutel uit de kolom id, verwijder het, geef de recent toegevoegde kolom de naam "id" en geef deze de primaire kenmerken. (Als u dat niet rechtstreeks in uw DB-software kunt doen, stel dan de eigenschappen Uniek, Auto-Increment, etc. in)

U kunt de kolom ook naar voren verplaatsen (MySQL-syntaxis):

ALTER TABLE table_name MODIFY COLUMN id int(11) FIRST;

Maar er is nog iets dat ik heel graag zou willen zeggen. Het is niet zo slecht geweest op deze vraag als ik elders heb gezien, maar mensen: het is allemaal goed en wel om mensen te vertellen dat het GEWOONLIJK geen goed idee is, maar dat is geen antwoord op de vraag. Zeg alsjeblieft niet "Doe dat niet" tenzij je de use-case van de persoon al kent.

In andere forums ben ik enorm gefrustreerd door mensen die zeiden "Waarom wil je dat doen?" of "Doe dat niet", en dan de vraag niet beantwoorden. Ze hebben me niet de eer gegeven om al te KENNEN dat het geen standaardpraktijk is, en ze dachten dat ik niet al wist dat het geen gewone use-case was.

Mensen op deze pagina zijn niet zo slecht geweest en ik probeer ze niet te kiezen. Ik vermaant alleen maar: controleer eerst je eigen gedrag voordat je aan het college gaat. Iemand heeft een vraag gesteld en hoewel waarschuwingen een goed idee kunnen zijn, is het waarschijnlijk veilig om aan te nemen dat ze een REDEN hebben om een ​​antwoord te willen.

Einde van tirade.


3
2017-12-17 03:25



De ID wordt meestal gegenereerd door de database als een automatisch oplopende PK. Je kunt het niet (en zou het echt niet nodig moeten hebben).


-1
2017-11-28 20:06