NePo
Spalis 20, 2006

Datos ant bėgių

Aš jau sukūriau savo pirmąją programą Ruby on Rails. Tie, kas atidžiai skaitė pastebėjo, kad naują note galima įterpti bet kurią datą. Galbūt kai kam tai yra gerai, tačiau man prisireikė tokį dalyką uždrausti ir pasirodė, kad apie tai informacijos ne tiek jau ir daug.

Taigi mano tikslas uždrausti informacijos įvedimą atbuline data.
Pirmiausiai aptarsiu savo sugalvotus būdus kaip tai padaryti:
1) Atsidaryti failą views/notes/_form.rhtml ir vietoj kodo:

<%= datetime_select 'note', 'created_at' %>

parašyti savo, kuris sugeneruoja tik šiandienos ir busimas datas. Rašymo daug, nelabai efektyvu, iš bėdos patys tokį kodą pasirašyti galėtumėt.
2) turi labai daug validation rules, galbūt kokia nors kaip tik tiktų man? Aš neradau, bet, jeigu kas nors žinote, pasidalinkit.
3) Gauti POST perduodamas reikšmes ir jas tikrinti. Pasirodo tai visai paprasta, bet kaip tradiciškai atveju naudingos informacijos nėra daug.

Taigi nusprendžiau įgyvendinti trečiajį būdą, tiems, kurie neatsimena arba nežino kaip atrodo įrašų įterpimo forma gali pasižiūrėti čia.
Norėdami uždrausti įrašo įterpimą atbuline data atsidarysime failą controlers\noter_controler.rb ir redaguosime metodą create kurio kodas atrodo taip:

def create
@note = Note.new(params[:note])
if @note.save
flash[:notice] = 'Note was successfully created.'
redirect_to :action => 'list'
else
render :action => 'new'
end
end

Kad jums būtų aiškiau, ką aš darau, pateiksiu trumpas aukščiau parodytos formos html ištraukas

...
<label for="note_created_at">Created at</label>
<select name="note[created_at(1i)]"><option value="2006" /></select> <select name="note[created_at(2i)]"><option value="10" /></select> <select name="note[created_at(3i)]"><option value="16" /></select>

Šiuo atveju mes tikrinsime datą, bet nekreipsime dėmėsio į laiką, galbūt būtų galima į tikrinimą dar įtraukti ir valandas, bet minučių tikrai ne, nes dažniausiai pranešimo parašymas užtrunka ne vieną minutę, žmogų versti nustatinėti laiką būtų nepadoru.
Po pataisymo create metodo kodas toks:

def create
@getdate=Date.parse(params[:note]["created_at(1i)"]+"-"+params[:note]["created_at(2i)"]+"-"+params[:note]["created_at(3i)"])
if (@getdate >= Date.today())
@note = Note.new(params[:note])
if @note.save
flash[:notice] = 'Note was successfully created.'
redirect_to :action => 'list'
else
render :action => 'new'
end
else
flash[:notice] = 'Cant do for yesterday.'
redirect_to :action => 'new'
end
end

params[:note] - paima visas POST masyvo reikšmes, norėdami prieti prie konkrečios, nurodome, kuri reikšmė mus domina params[:note][”created_at(1i)”]
Gautas kintamasis be abejonės yra string tipo, todėl jį reikia paversti į date, tam naudojama komanda Date.parse. O paskui tik pridedamas if, patikrinti ar įrašo data nėra senesnė nei šiandien.
Viskas.
Pasiūlymų bus?

Panašūs straipsniai


“Datos ant bėgių” komentarų: 2

  1. enc

    efektyviau būtų neleisti iš viso įvedinėti datos, o įrašant žinutę į duomenų bazę tiesiog panaudoti įvedimo laiką. Prie to pačio - pridėti dar vieną laukelį lentelėje, kuris rodytų kokia yra raštelio būsena (juodraštis/išpublikuotas), o kiekvieną kartą redaguojant raštelį ir jį išsaugant - išsaugojimo metu atnaujinti sukūrimo laika (arba palikti senąjį, čia jau kaip pats norėsi).

  2. Rimantas

    Jei modelis turi laukus pavadintus created_at, updated_at, tai kaip enc ir sakė, jokių formų nereikia, RoR viskuo pasirūpins automatiškai - created_at bus sukūrimo laikas, updated_at - redagavimo.

    Šiuo atveju paprasčiausias tikrinimas - naudotis normalia RoR siūloma validacija.
    Modelyje pridedi metodą:

    def validate
    errors.add_to_base “Date cannot be in the past” if self.created_at Range.new(Time.now, 30.days.from_now), :message => “must be within 30 days from now”
    end

    Beje, tas išsidirbinėjimas su @getdate (ir kodėl čia instance variable, užtenka gi local) nereikalingas. Jei pirmoje eilutėje turi
    @note = Note.new params[:note], tai atributas created_at jau bus teisingas inicializuotas,
    imkite ir naudokite, t.y. vietoj @getdate = … if @getdate tiesiog galima naudoti self.created_at (ką aš ir darau variante su validate metodu).

    Tik čia niuansai, kur Date, o kur Time objektai (jei laukas yra date tipo, tai bus Date, jei datetime - Time).

Rašyti komentarą

Jūs privalote prisijungti jeigu norite rašyti komentarą.