Javascript: Przypisać this, czyli metoda apply i call obiektu Function
Opublikowano 2011-01-02 12:47:30 JavaScript
Czasami, szczególnie przy obiektowym javascriptcie istnieje potrzeba określenia czym jest this w danej funkcji/metodzie. Istnieją dwa sposoby określenia this, za pomocą metod apply i call obiektu Function:
function car() {
this.name = 'car';
}
car.prototype.getName = function() {
alert('car.getName(): '+this.name);
}
function person() {
this.name = 'person';
}
person.prototype.getName = function() {
alert('person.getName(): '+this.name);
}
person.prototype.test1 = function(car) {
car.getName.apply(this);
}
person.prototype.test2 = function(car) {
car.getName.call(this);
}
var car = new car();
var person = new person();
car.getName();
person.getName();
person.test1(car);
person.test2(car);
Pierwszym parametrem w obydwu metodach jest zmienna, która w wywołanej funkcji/metodzie będzie przypisana do this. Wykonując powyższy kod, tworzymy 2 obiekty, person i car. Wywołujemy po koleji metody getName obudwu obiektów i dostajemy w komunikatach:
car.getName(): car person.getName(): person
Czyli wszystko standardowo. W obiekcie car this=car, a w obiekcie person this=person; W kolejnych 2 wywołaniach, metody test1 i test2 obiektu person, wywołujemy metode getName obiektu car, przekazując w pierwszym argumencie metod apply/call this, czyli person(bo wywołujemy z poziomu obiektu person). Spodziewamy się wywołać z poziomu obiektu car metode getName z this=person. Brzmi absurdalnie, ale w kolejnych dwóch komunikatach dostajemy:
car.getName(): person car.getName(): person
Przykład ten nie niesie większego sensu, ale wydaje mi się, że dobrze oddaje ideę działania tych metod. Metody apply i call różnią się sposobem przekazywania dodatkowych argumentów, co nie zostanie omówione w tym artykule.
CakePHP: HABTM - podstawy relacji hasAndBelongsToMany
Opublikowano 2010-12-26 22:01:55 HABTM CakePHP
1. Wprowadzenie
W artykule tym opiszę wszystkie istotne informacje dotyczące relacji HABTM(hasAndBelongsToMany). Na początku podam przykład takiej relacji wzięty z tej strony. Mamy artykuły i kategorie; artykuł może być przypisany do wielu kategorii, a kategoria może posiadać wiele artykułów. To jest istotą relacji HABTM. Aby utworzyć tą relację konieczne jest stworzenie w bazie danych, tabeli łączącej artykuły z kategoriami. Definicja w kodzie wygląda następująco:
<?php
//definicja modelu artykułów
class Article extends AppModel {
var $name = 'Article';
var $hasAndBelongsToMany = array('Category');//definicja relacji HABTM
}
<?php
//definicja modelu kategorii
class Category extends AppModel {
var $name = 'Category';
var $hasAndBelongsToMany = array('Article');//definicja relacji HABTM
}
W powyższym kodzie nie zdefiniowałem tabeli łączącej obydwa modele, jest spowodowane tym, że CakePHP domyślnie przyjmuje nazwę wziętą z konwencji; w tym wypadku articles_categories. Dodatkowo zostanie utworzony automodel ArticlesCategory, który umożliwi dostęp bezpośrednio do danych zawartych w tabeli łączącej. Należy jednak pamiętać o tym, że utworzony automodel nie jest powiązany ani z artykułem, ani z kategorią. Powiązanie takie można wywołać ręcznie:
//utworzenie relacji naszego automodelu do kategorii $this->Article->ArticlesCategory->bindModel(array(‘belongsTo’=>array(‘Category’)));
2. Modyfikacja relacji
Co jednak jeśli nazwa automodelu nam nie pasuje? Albo chcemy użyć innej nazwy tabeli łączącej? Nazwe te możemy dowolnie modyfikować, należy jednak pamiętać o tym aby zmiany wprowadzić w obu modelach. Wprowadzenie ich tylko w jednym modelu będzie skutkowało dużym bałaganem i niespodziewanym zachowaniem aplikacji.
<?php
//definicja modelu artykułów
class Article extends AppModel {
var $name = 'Article';
var $hasAndBelongsToMany = array(
'Category'=>array(
'with'=>'ArticlesCategories' //nowa nazwa automodelu
,'joinTable'=>'articles_categories_joined' //nowa nazwa tabeli łączącej
)
);//definicja relacji HABTM
}
<?php
//definicja modelu kategorii
class Category extends AppModel {
var $name = 'Category';
var $hasAndBelongsToMany = array(
'Article'=>array(
'with'=>'ArticlesCategories' //nowa nazwa automodelu
,'joinTable'=>'articles_categories_joined' //nowa nazwa tabeli łączącej
)
);//definicja relacji HABTM
}
Po zastosowaniu podanego wyżej kodu nasz automodel będzie się nazywał ArticlesCategories a tabela łącząca articles_categories_joined.
3. Analiza relacji
Wrócmy jednak do nazewnictwa proponowanego przez konwencję CakePHP. Jeśli chcemy wejść w szczegóły relacji HABTM, jest to nic innego niż 2 relacje hasMany z zastosowaniem modelu pośredniego. Podaję przykład jak utworzyć relację zachowującą się podobnie jak HABTM:
//definicja modelu artykułów
class Article extends AppModel {
var $name = 'Article';
var $hasMany = array('ArticleCategory');
}
//definicja modelu kategorii
class Category extends AppModel {
var $name = 'Category';
var $hasMany = array('ArticleCategory');
}
//definicja modelu łączącego
class ArticleCategory extends AppModel {
var $name = 'ArticleCategory';
var $belongsTo = array('Article','Category');
}
Jak widać wymaga to zdefiniowania dodatkowego modelu, pełniącego rolę łącznika. Nie polecam definiowania relacji w ten sposób, przykład ten został podany jedynie w celu zrozumienia zasady działania relacji HABTM.
4. Tworzenie i usuwanie relacji
Relacja HABTM jest dość specyficzną relacją. Aby przypisać artykuł o id=1 do kategorii o id=1 wywołujemy:
$this->Article->save(array(
'Article' => array(
'id' => 1,
),
'Category' => array(
'Category' => array(1),
),
));
Jeżeli chcemy przypisać nasz artykuł dodatkowo do kategorii 2 może skorzystać z kodu:
$this->Article->save(array(
'Article' => array(
'id' => 1,
),
'Category' => array(
'Category' => array(2),
),
));
Spowoduje to jednak usunięcie relacji z kategoria o id=1. Należy zatem pamietać, że przy modyfikacji relacji HABTM CakePHP najpierw kasuje wszystkie istniejące relacje. Poprawny kod wygląda następująco:
$this->Article->save(array(
'Article' => array(
'id' => 1,
),
'Category' => array(
'Category' => array(1,2),
),
));
Jak można się już domyślić, jeśli chcemy aby nasz artykuł nie należał do żadnej kategorii wywołujemy:
$this->Article->save(array(
'Article' => array(
'id' => 1,
),
'Category' => array(
'Category' => array(),
),
));
Aby zmienić to zachowanie można skorzystać z add-delete-habtm-behavior. Osobiście nie korzystałem z tego dodatku, ale w niektórych przypadkach może on okazać sie użytyczny.
5. Więcej informacji
W przyszłości planuję opisać sposób filtrowania danych objętych relacją HABTM.
MySQL: Reorganizacja kluczy głównych tabeli
Opublikowano 2010-12-22 23:55:00 SQL
Krótki post o tym jak należy postępować gdy chcemy dokonać reogranizacji kluczy głównych tabeli. Tyczy się to tylko tabel, które mają indeks główny numerowany automatycznie. Przykładowo mamy tabelę w której istnieją wpisy dla kluczy głównych: 1,3,5,10, a chcemy ją tak przenumerować, żeby te klucze przyjmowały wartości: 1,2,3,4. Rozwiązanie sprowadza się do 3 zapytań SQL:
ALTER TABLE `users` DROP `id`; ALTER TABLE `users` AUTO_INCREMENT = 1; ALTER TABLE `users` ADD `id` int UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;
Oczywiście rozwiązanie posiada jedną ogromną wadę: nadaje się do zastosowania tylko tam, gdzie nie mamy relacji z tabelą którą modyfikujemy. Na szczęscie mój obiekt testowy spełniał to założenie.
CakePHP: Optymalizacja tabel ACL
Opublikowano 2010-11-02 11:55:11 CakePHP SQL Optymalizacja ACL
Natknąłem się w sieci na ciekawy kawałek kodu SQL, który drastycznie zwiększa wydajność zapytań do tabel ACL. Zmiana polega jedynie na nałożeniu indeksów i kluczy obcych. Kod został znaleziony na grupie dyskusyjnej CakePHP.
/* ACL Tables */ CREATE TABLE acos ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, parent_id INT DEFAULT NULL, model VARCHAR(255) DEFAULT '', foreign_key INT UNSIGNED DEFAULT NULL, alias VARCHAR(255) DEFAULT '', lft INT DEFAULT NULL, rght INT DEFAULT NULL ) ENGINE = INNODB; -- table name is quoted because it is a reserved word CREATE INDEX idx_acos_lft_rght ON `acos`(lft,rght); CREATE INDEX idx_acos_alias ON `acos`(alias); CREATE INDEX idx_acos_model_foreign_key ON `acos`(model(255),foreign_key); CREATE TABLE aros ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, parent_id INT DEFAULT NULL, model VARCHAR(255) DEFAULT '', foreign_key INT UNSIGNED DEFAULT NULL, alias VARCHAR(255) DEFAULT '', lft INT DEFAULT NULL, rght INT DEFAULT NULL ) ENGINE = INNODB; -- table name is quoted because it is a reserved word CREATE INDEX idx_aros_lft_rght ON `aros`(lft,rght); CREATE INDEX idx_aros_alias ON `aros`(alias); CREATE INDEX idx_aros_model_foreign_key ON `aros`(model(255),foreign_key); CREATE TABLE aros_acos ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, aro_id INT UNSIGNED NOT NULL, aco_id INT UNSIGNED NOT NULL, _create CHAR(2) NOT NULL DEFAULT 0, _read CHAR(2) NOT NULL DEFAULT 0, _update CHAR(2) NOT NULL DEFAULT 0, _delete CHAR(2) NOT NULL DEFAULT 0 ) ENGINE = INNODB; -- table names are quoted because they are reserved words CREATE UNIQUE INDEX idx_aros_acos_aro_id_aco_id ON `aros_acos`(aro_id, aco_id); ALTER TABLE aros_acos ADD CONSTRAINT FOREIGN KEY (aro_id) REFERENCES `aros`(id); ALTER TABLE aros_acos ADD CONSTRAINT FOREIGN KEY (aco_id) REFERENCES `acos`(id);
Aktualizacja licznika długu publicznego - dane z VI 2010
Opublikowano 2010-09-19 23:26:00 licznik długu
Kolejna aktualizacja licznika długu publiczego. Dane są obecnie pobierane z okresu 01.06.2009 - 31.05.2010. Aktualizacja spowodowała skok licznika o 25 mld złotych do przodu! Jest to rekordowy skok odkąd uruchomiono licznik. Szczegółowe dane można zobaczyć na stronie projektu.
Dodatkowo licznik długu publicznego obchodzi swoje ciche pierwsze urodziny. ;) Od tego czasu zyskał znaczy rozgłos. W planach jest stworzenie niezależnego skryptu PHP zwracającego wartość tekstową lub graficzną aktualnego długu.
Standardowo informuję: Aby dane licznika się zaktualizowały może być konieczne wyczyszczenie cache, lub po prostu wciśnięcie klawisza F5 na stronie z licznikiem.