2013-02-08 13 views
16

Mam dwa powiązane modele - powiedzmy Activity i Step. Activity has_many :steps i Step belongs_to :activity co oznacza, że ​​tabela dla steps ma kolumnę activity_id.Zapobieganie zmianie jednego pola w modelu szyny

To jest w wersji Hobo 1.3, więc Rails 3.0.

To, czego chcę, to zagwarantowanie, że po utworzenie nie można przenieść kroku do innego Activity. Nie chcemy zmieniać pola activity_id.

Usunąłem pole z formularzy edycji, ale szukam silniejszego ograniczenia. Zasadniczo chcę sprawdzić na update (nie na create), że kolumna nie jest dotykany. Dokumentacja Hobo nie sugeruje niczego podobnego w Hobo, więc patrzę na Rails validations, ale do tej pory nie znalazłem ograniczenia "tylko rób to w aktualizacji", które pamiętam, ani potwierdzenia, że ​​coś nie jest wymiana pieniędzy.

Odpowiedz

29

Możesz zadeklarować atrybut jako read_only z attr_readonly :your_field_name. Ale to nie spowoduje błędu, jeśli spróbujesz zapisać ten atrybut, nie powiedzie się po cichu. (Ten atrybut będzie ignorowany dla wszystkich SQL-Updates)

Inną opcją może być, aby napisać walidacji w tym przypadku, może wyglądać następująco:

class Step < ActiveRecord::Base 
    validate :activity_id_not_changed 

    private 

    def activity_id_not_changed 
    if activity_id_changed? && self.persisted? 
     errors.add(:activity_id, "Change of activity_id not allowed!") 
    end 
    end 
end 

persisted? zwraca true, jeśli nie jest to nowy rekord i nie jest zniszczony.

Linki:

http://api.rubyonrails.org/classes/ActiveRecord/ReadonlyAttributes/ClassMethods.html#method-i-readonly_attributes

http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-persisted-3F

+0

'attr_readonly' działa jak w reklamie, b ut może powodować marszczenie z innym aspektem aplikacji. Wypróbuję podejście walidacyjne jutro i zobaczę, czy to działa lepiej. – pjmorse

+0

Jeśli naprawdę potrzebujesz zmienić identyfikator gdzieś indziej w swojej aplikacji, możesz to zrobić nawet z podejściem sprawdzania poprawności z następującymi: 'step.save (: validate => false)' – Deradon

+0

To nie jest kwestia zmian gdzie indziej; to kopia obiektu. (Więc, powiedzmy, hipotetycznie skopiowaliśmy "Czynność" w sposób, który również skopiował wszystkie "Kroki", z jakiegoś powodu, który nie działa, a jeszcze nie zagrzebałem się wystarczająco głęboko w kodzie, aby zrozumieć, czy ta zmiana go złamała .) – pjmorse

Powiązane problemy