sobota, 21 sierpnia 2010

Wykonane

Co zostało wykonane jak do tej pory w rbklaser? Innymi słowy co działa.

  • logowanie/wylogowanie
  • Najbliższe egzaminy
  • Źródła nauki do egzaminów, dodawane bez przeładowywania strony
  • Ograniczenie możliwości w modelach Exam i Resource.

Najbliższe działania
  • Rejestracja użytkowników
  • Parsowanie markdown w polu resources.content
  • Testy do wszystkiego co napisałem. Do tej pory są tylko testy modeli, niestety na kontrolerach się zawiesiłem i przestałem pisać testy jakiekolwiek ;/
  • Stronicowanie na źródeł nauki na stronach egzaminów

Korzystanie z autentykacji w całej aplikacji

Jeśli mamy jeden warunek do sprawdzenia czy użytkownik jest zalogowany, możemy umieścić go w before_filter ApplicationController. Dzięki temu, że reszta kontrolerów (co można zmienić) dziedziczy po ApplicationController, będziemy mieli pewność, że w nich też wykona się ten filtr:

class ApplicationController < ActionController::Base
  before_filter :user_
  
  def user_
    @user_id = session[:user_id]
    @is_admin = User.find(@user_id).is_admin if @user_id
  end
Dzięki temu możemy w akcji jakiegoś innego kontrolera:
...
if @is_admin
  @model_object.destroy
  redirect_to :back, :notice => "success"

piątek, 20 sierpnia 2010

Auth, Ajax

Nie ma jeszcze rejestracji i aktywacji konta. Zrobię to gdy skończę AJAXa.

Robię to w oparciu o post teamona. Mam zamiar zrobić całą obsługę egzaminów (dodawanie niekoniecznie, tylko usuwanie, uaktualnianie) w oparciu o AJAXa. Nie z racji, że tak będzie fajniej (chodź będzie), ale żeby się nauczyć. Przy okazji muszę douczać się jquery.

czwartek, 19 sierpnia 2010

Problemy ruby 1.9

Zainstalowane mam Ruby 1.9.1, okazuje się, że słabo ta wersja współpracuje z gemem mysql 2.8.1. Stringi w widokach są inaczej kodowane niż w bazie danych i następuje kolizja.

Można jednak "Monkey patchnąć" klasę Mysql.

require 'mysql'

class Mysql::Result
  def encode(value, encoding = "utf-8")
    String === value ? value.force_encoding(encoding) : value
  end
  
  def each_utf8(&block)
    each_orig do |row|
      yield row.map {|col| encode(col) }
    end
  end
  alias each_orig each
  alias each each_utf8

  def each_hash_utf8(&block)
    each_hash_orig do |row|
      row.each {|k, v| row[k] = encode(v) }
      yield(row)
    end
  end
  alias each_hash_orig each_hash
  alias each_hash each_hash_utf8
end

Plik zapisujemy w config/initializers/mysql-281-patch.rb i wszystko działa jak powinno.

poniedziałek, 16 sierpnia 2010

Jak proste jest wyszukiwanie

Dodałem model resouces, relacje między nim a examsami.
Jako kolejny krok napisałem (aby mieć pojęcie jak, bo przypominam, zę uczę się railsów od 0 na tym projekcie, więc co przeczytam w tutorialu/referencjach to próbuję jakoś użyć w projekcie :)

Wyszukiwanie:

# Akcja w kontrolerze:

  def search
    if params[:q]
      @exams = Exam.where("name like ? or description like ?", params[:q], params[:q]+"%")
    end
  end

# Widok:
<%= form_tag('/exams/search', :method => "post") do %>
  <%= label_tag(:q, "Szukaj: ") %>
  <%= text_field_tag(:q) %>
  <%= submit_tag("Szukaj") %>
 <% end %>
 
<% if @exams.class != NilClass %> 
  <% unless @exams.blank? %>
  

Wyniki wyszukiwania egzaminów

<% @exams.each do |exam| %> Tytuł: <%= exam.name %> <%= link_to "Pokaż", exam %> <% end %> <% else %> Nie znaleziono niczego <% end %> <% end %> # Oraz routing # deprecated chyba? #map.search 'exams/search', 'exams#search' match 'exams/search' => 'exams#search'

Wyszukiwanie działa zdecydowanie fajnie.

Kolejny krok to użycie paperclipa do avatarów.

sobota, 14 sierpnia 2010

Autentykacja w Ruby on Rails

Na potrzeby rbklasera dodałem w modelu User jedną metodę "auth":
def self.auth(email_try, pass_try)
             pass_try = Digest::SHA1.hexdigest(pass_try)
             u = User.where("email = ? AND pass = ?", email_try, pass_try)
             return u unless u.blank?
             nil
      end

Chciałbym zapytać czy wg Was takie coś wystarczy? Czy może lepszym wyjściem będzie jakiś plugin (może jakiś co implementuje REST)?

Pierwszy model w ActiveRecord

Zdążyłem jedynie poczytać o Modelach w RoR, trochę o walidacji.
Postanowiłem napisać od razu model użytkownika, przy okazji utworzyć bazę i w niej pierwszą tabelę.

Kod modelu:
require 'digest/sha1'

class User < ActiveRecord::Base
      validates_presence_of :name
      validates_presence_of :sec_name
      validates_presence_of :nrdziennika
      validates_presence_of :is_admin
      validates_presence_of :pass
      validates_presence_of :email
      
      validates_format_of :email, :with => /^(?:(?:[\-+%=_'a-z0-9]+)(?:\.(?![\.@]))?)+@(?:[a-z0-9\-]+\.)+[a-z]+/,
       :message => "Invalid format"

      validates_confirmation_of :email
      validates_confirmation_of :pass
      validates_presence_of :email_confirmation
      validates_presence_of :pass_confirmation
      
      validates_numericality_of :nrtel
      validates_uniqueness_of :email
      
      before_save :salt_password
      
      protected
      def salt_password
             self.pass = Digest::SHA1.hexdigest(self.pass)
      end
end

Bardzo prosto się dodaje np. 'solenie hasła', troszkę przyjemniej niż w django.
Widać, że ActiveRecord to prekursor w swojej kategorii.