2016-01-09 2 views
1

Моя модель имеет атрибут void. Если значение void истинно, я хочу, чтобы запись была только для чтения. Я пробовал:Рельсы делают запись readonly после атрибута обновления

def readonly? 
    self.void 
end 

, но это отключить бы меня от сохранения записи, потому что пустота уже правда, прежде чем я сохранил его. Сохранение записи с void=true приведет к исключению ActiveRecord::ReadOnlyRecord. Поэтому я никогда не мог хранить void=true в базе данных.

Как я могу сделать запись readonly после того как я сохранить void=true

+0

Вы можете подтвердить достоверность? –

+0

@OlegSobchuk Я только проверяю другие поля и не пусто, поэтому я не думаю, что это имеет значение? (или я не прав?). Сохранение записи после установки 'void = true' приведет к тому, что она поднимет ошибку« ActiveRecord :: ReadOnlyRecord », которая, как представляется, не зависит от проверки рельсов. – harinsa

ответ

1
def readonly? 
    persisted? && void 
end 

EDIT

он будет работать только для новых записей.

, если вам нужно использовать для сохранялось записей вы можете сделать это следующим способом:

в модели:

attr_accessor :editable 

def readonly? 
    editable || !void ? false : true 
end 
+0

, похоже, не работает, я думаю, что это будет работать, только если объект является new_record ?. – harinsa

+0

отредактирован, проверьте это. И если вы нашли мой ответ полезным, пожалуйста, отметьте его полезным, спасибо –

+0

. Я полагаю, что-то сделать с 'editable'? Я думаю, что это «ноль», как есть. – harinsa

0

Вы можете попытаться проверить, если там было изменения атрибута void?

E.g.

def readonly? 
    !void_just_changed? && void 
end 

def void_just_changed? 
    void_was.blank? && void? 
end 

Вы можете изменить void_just_changed? на то, что вам подходит, например позволяют ничтожным установить обратно в ложь.

+0

Так что мне нужно добавить еще одно поле для отслеживания изменений? Надеюсь, что есть более чистый способ :( – harinsa

+0

Нет, это не другое поле. 'Void_was' - это метод сгенерированный Rails, который возвращает вам значение' void' перед изменением. См. Http://api.rubyonrails.org/ классы/ActiveModel/Dirty.html –

0

Я нашел способ сделать это без добавления каких-либо переменных, однако в результате поведение немного отличается.

def readonly? 
    begin 
    prev = self.class.find(self.id) 
    prev.void && self.void 
    rescue ActiveRecord::RecordNotFound 
    false 
    end 
end 

С помощью этого метода, запись будет корректно отмечен только для чтения, но изменение его атрибутов разрешено, вы просто не сможете сохранить его. И наоборот, если вы вручную вернете true с readonly?, то ReadOnlyRecord будет рейзом (что, я думаю, предпочтительнее). Было бы здорово, если кто-нибудь сможет объяснить, почему.

0

У меня есть еще один вариант:

def readonly? 
    !persisted? || void_changed? ? false : void 
    end 

своих средства каждый раз, когда вы меняете недействительные записи не только для чтения в других случаях readlonly? зависит от void