🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.lang.ruby
Article #824

Re: RoR vs PHP

#824
From: Jaroslaw Zabiello
Date: Tue, 01 Jan 2008 18:11
108 lines
4856 bytes
On Tue, 01 Jan 2008 16:28:01 -0000, Maciej Piechotka  
<uzytkownik2@gmail.com> wrote:

> 1. W Ruby się da ale *ActiveRecord* tego *nie* *obsługuje* (przynajmniej
> tak piszą sami w wiki).

Myśle, że da się i w AR ale nie na wbudowanych makrach bo są zabyt  
prymitywne. Trzeba to zrobić na własnych metodach. Tu masz działający kod  
dla pierwszego przypadku. Użyłem tu Sequela (bo jest dużo lepszy od AR):

require 'rubygems'
require 'sequel_model'

DB = Sequel('mysql://root:@localhost/test')

class Parent < Sequel::Model(:parents)
   # Ta deklaracja jest opcjonalna
   # Używam jej aby stworzyć tabelę w bazie
   set_schema do
     primary_key :id
     varchar     :type, :null => false
     varchar     :pole_parent
     varchar     :pole1
     varchar     :pole2
   end
end

# Tworzymy tabelę, (jeśli istniała zostanie usunięta)
Parent.create_table!

# Opcjonalnie trochę przyblokuję możliwość
# zapisu do niewłaściwego pola
module DatabaseSecurity
   def forbidden(fields)
     forbidden_fields = fields & changed_columns
     unless forbidden_fields.empty?
       raise "#{self.class} has no access to #{forbidden_fields.join(',  
')}!"
     end
   end
end

class Parent < Sequel::Model(:parents)
   include DatabaseSecurity
   before_save do
     forbidden [:pole1, :pole2]
     self.type = self.class.to_s
   end
end

# Kolejne klasy nie mają swoich tabel,
# operują na tej jednej, odziedziczonej

class Child1 < Parent
   before_save do
     forbidden [:pole_parent, :pole2]
     self.type = self.class.to_s
   end
end

class Child2 < Parent
   before_save do
     forbidden [:pole_parent, :pole1]
     self.type = self.class.to_s
   end
end

# No to potestujmy:

Parent.create :pole_parent => 'parent value'
Child1.create :pole1 => 'child1 value'
Child2.create :pole2 => 'child2 value'
Parent.all.map{|row| p row.values}
# wyniki:
# {:type=>"Parent", :pole_parent=>"parent value", :pole1=>nil,  
:pole2=>nil, :id=>1}
# {:type=>"Child1", :pole_parent=>nil, :pole1=>"child1 value",  
:pole2=>nil, :id=>2}
# {:type=>"Child2", :pole_parent=>nil, :pole1=>nil, :pole2=>"child2  
value", :id=>3}


> Tzn. Zawsze da się pisać save/select/find przy
> użyciu SQL ale chyba nie o to chodzi w korzystaniu z AR.

Co ty powiadasz. Właśnie o to chodzi, że kontroler w ogóle nie powinien  
posługiwać się metodami specyficznymi dla danego ORM'a. Zgodnie z zasadą  
"cienkiego kontrolera i bogatego modelu" model powinien ukrywać swoją  
implementację tak, abym mógł bez żadnych zmian w kontrolerze wymienić go  
na inną implementację. Z tego wniosek, że jedyne metody modelu jakie są  
dostępne dla kontrolera to custom methods. I można je w Ruby tak owrapować  
z SQL czy bez że uzyskać te łamańce połączeniowe jakie podałeś. Różnica  
tylko taka, że w Active Record będę musiał użyć SQL'a. Zaś w wpadku  
Sequela tego nie muszę robić, bo jest wystarczająco elastyczny.

> 2. Nie zawsze zaczyna się od tabel - czasami tworzy się kod równolegle.

Dane biznesowe są ważniejsze od aplikacji. Zrozumiałem, że miałeś sytuację  
że jest dana baza i należy jakoś ją zamapować w Ruby.

Tworzenie struktur tabel za pomocą ORM'a nigdy nie będzie doskonałe i nie  
jest możliwe uniknąć SQL jeśli chcemy naprawdę mieć porządną i  
nietrywialną strukturę. Nawet Hibernate ci nic nie pomoże. Optymalizacja  
bazy wymaga użycia specificznych dla niej rozszerzeń SQL'a i już.

-- 
Jarosław Zabiełło
http://blog.zabiello.com
Technical Details
Message-ID: <op.t39jhmarr2rg33@jzmbp.local>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.gazeta.pl!not-for-mail
References: <fl6ahk$m1q$1@inews.gazeta.pl> <op.t351icnsr2rg33@jzmbp.local> <fl93bh$d8p$1@inews.gazeta.pl> <r4il45-1ar.ln1@router.piechotka.com.pl> <op.t358bkfwr2rg33@jzmbp.local> <fl9aau$9b9$5@inews.gazeta.pl> <20071231084648.6d47feda.gryf_esm-no@spam-o2.pl> <op.t37dq3ydr2rg33@jzmbp.local> <0enn45-u25.ln1@router.piechotka.com.pl> <op.t37qnpdrr2rg33@jzmbp.local> <3pbo45-ha7.ln1@router.piechotka.com.pl> <op.t3777x1jr2rg33@jzmbp.local> <jtip45-n8c.ln1@router.piechotka.com.pl> <op.t388lvhur2rg33@jzmbp.local> <h96q45-37f.ln1@router.piechotka.com.pl>

Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.gazeta.pl!not-for-mail
From: "Jaroslaw Zabiello" <abuse@tpnet.pl>
Newsgroups: pl.comp.lang.ruby
Subject: Re: RoR vs PHP
Date: Tue, 01 Jan 2008 18:11:36 -0000
Organization: "Portal Gazeta.pl -> http://www.gazeta.pl"
Lines: 108
Message-ID: <op.t39jhmarr2rg33@jzmbp.local>
References: <fl6ahk$m1q$1@inews.gazeta.pl> <op.t351icnsr2rg33@jzmbp.local> <fl93bh$d8p$1@inews.gazeta.pl> <r4il45-1ar.ln1@router.piechotka.com.pl> <op.t358bkfwr2rg33@jzmbp.local> <fl9aau$9b9$5@inews.gazeta.pl> <20071231084648.6d47feda.gryf_esm-no@spam-o2.pl> <op.t37dq3ydr2rg33@jzmbp.local> <0enn45-u25.ln1@router.piechotka.com.pl> <op.t37qnpdrr2rg33@jzmbp.local> <3pbo45-ha7.ln1@router.piechotka.com.pl> <op.t3777x1jr2rg33@jzmbp.local> <jtip45-n8c.ln1@router.piechotka.com.pl> <op.t388lvhur2rg33@jzmbp.local> <h96q45-37f.ln1@router.piechotka.com.pl>
NNTP-Posting-Host: 89.124.240.242
Mime-Version: 1.0
X-Trace: inews.gazeta.pl 1199211098 1422 89.124.240.242 (1 Jan 2008 18:11:38 GMT)
X-Complaints-To: usenet@agora.pl
NNTP-Posting-Date: Tue, 1 Jan 2008 18:11:38 +0000 (UTC)
X-User: hipertracker
User-Agent: Opera Mail/9.25 (MacIntel)
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit