четверг, 16 июля 2009 г.

Передача JS массива Ajax $.post запросом. Send JS array to server using JQuery $.post method

Часто возникает проблема передачи массива (сформированного средствами JavaScript) Ajax запросом, используя библиотеку JQuery и ее методы $.get, $.post

На самом деле задача доволно несложная:

ids_list = array(1,2,3,4,5);
$.post("/controller/action",
   {'ids[]': ids_list},
   function(result){
     //обработка данных которые вернул сервер
  }
);

Достаточно указать что вы передаете массив, с помощью скобок [].

Хотя, существуют реализации, с использованием join() и прочих "ручных" методов преобразование массива в его JSON аналог, но пример показанный выше намного проще и элегантнее.

понедельник, 22 июня 2009 г.

Связи в моделях. Один ко многим

В предыдущей статье обсуждалась проблема связывания 2 моделей, как "1 к 1". Наша сегодняшняя тема - как связать модели один ко многим.

На самом деле, все не сложнее чем связь 1 к 1, потому чтобы не вдаваться в детали, сразу приведу пример:

class Order < ActiveRecord::Base
   belongs_to :user
end

class User < ActiveRecord::Base
   has_many :orders
end

Здесь описываем связь, когда каждый пользователь может иметь несколько заказов.

Как и в предыдущем примере, связь belongs_to в модели Order показывает что каждый ее экземпляр, может относится только к одному экземпляру модели пользователей (User).

В модели User есть новое для нас условие связи has_many :orders , которое, буквально дословно, означает, что каждый экземпляр класса (модели) User - имеет несколько экземпляров класса (модели) Order.

Вот впринципе и все описание. Теперь осталось рассмотреть несколько примеров использования :

Пример только в целях демонстрации, не используйте его для подсчета суммы:
user = User.find(id)
total = 0;
user.orders.each do |order|
   total += order.price
end

Правильно посчитать сумму можно так:
total = user.orders.sum(:price)

Мы легко можем оперировать свойством orders в цикле, где множественное число имени свойства показывает нам, что мы имеем дело с коллекцией экземпляров order, для конкретного экземпляра user.

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

new_order = Order.create(:price => 150.00)
user.orders << new_order

или еще проще:

user.orders << Order.create(:price => 100.00)

Где "<<" - операция добавления нового значения в массив (коллекцию)

На первый взгляд может показаться, что Рельса не очень гибкая и довольно громоздкая. Но на самом деле все не так - после того, как я опишу все связи моделей, я посвящу несколько статей нестандартным способам описания связей.

Основной принцип рельсы - минимальными усилиями, за минимальное количество времени, создать рабочее приложение. Потому все стандартные операции упрощены до предела, но с другой стороны - существуют очень мощные и гибкие механизмы для решения нестандартных задач. Профессионализм разработчика на рельсе, как раз и заключается в правильном понимании, а также грамотном использовании таких механизмов.

пятница, 19 июня 2009 г.

Связи в моделях. Один к одному

Я давно хотел написать серию публикаций о связях в моделях, все не доходили руки. Этой статьей я начну серию статей которая раскроет суть взаимодействия моделей в Ruby on Rails.
Связь один к одному
Если у читателей был опыт разработки с использованием БД, то вероятно вам уже известно, как создавать SQL запросы на выборку из разных таблиц. В Ruby on Rails все выглядит немного более привлекательно. Так как Active Record является полноценной ORM, то вполне понятно, что работа со связанными таблицами может быть гораздо удобнее.

Как уже вы знаете, каждой таблице в БД, в ROR(ActiveRecord) сопоставляет одноименный обьект (модель), правда стоит учитывать, что имя таблицы должно быть во множественном числе, в отличии от имени обьекта(модели). Также для доступа к каждому полю таблицы существует одноименный метод в модели (Например таблица users содержит поле name, то в модели оно доступно, как obj.name, где obj - объект класса User). Потому и говорят что таблица "мапится" моделью - что и есть основным принципом ORM. Детальнее тут.

Кроме этого, как уже мною было описано ранее,в публикациях касающихся Модели, она содержит также - множество дополнительных функций, предназначенных для обработки полученных данных (всевозможные выборки тут и детальнее тут, валидация, а также связи между моделями).

Так как вместо таблиц мы используем модели, то нам хотелось бы написать что-то типа такого:
user.address.street - где User и Adress єкземпляры классов соответствующих моделей, а street - свойство экземпляра класса адреса. Заманчиво, не правда ли?

Для того, чтобы написать подобное, использем SQL:

SELECT addresses.name
FROM addresses INNER JOIN users on users.id = addresses.user_id
нам бы пришлось выполнить запрос и достать из него нужное поле... Как по мне, то немного неудобно.

Так как же, все-таки, изменить модели, чтобы мы могли так ими оперировать?
Именно это и является темой данной статьи. Давайте рассмотрим запрос на SQL более детально, так как нам надо выяснить для себе некоторые моменты.

Для того, чтобы связать две таблицы как "1 к 1", нам необходимо выяснить для себя - какая таблица является родительской, а какая подчиненной.

Оказывается, это довольно-таки просто: рассмотрим 2 строку запроса, а именно условие обьеденения
users.id = address.user_id
Таблица Addresses содержит первичный ключ таблицы Users, что автоматически делает ее подчиненной.

Сформулируем словами связи между таблицами: таблица Users содержит таблицу Addresses с одной стороны, таблица Addresses относится к таблице Users - с другой стороны. Все вполне логично. Теперь посмотрим, как все выше сказанное реализовать в моделях RoR:

class Address < ActiveRecord::Base
   belongs_to :user
   # дальше идет код который описывает управление данными модели
end
class User < ActiveRecord::Base
   has_one :address
   # дальше идет код который описывает управление данными модели
end

В самом начале описания модели, мы указываем как она связана с другими моделями. Для реализации связи "1 к 1", достаточно "сказать" модели User - что она has_one (содержит один) Address, а Address в свою очередь belongs_to(содержит) User. Вот и все!

Что мы получили в результате
С этого момента модели являются связанными между собой, и при построении запросов типа: user.address.street ActiveRecord автоматически будет добавлять связи.

Теперь возможно, используя связи, пользоваться подчиненной моделью (таблицей) как частью таблицы родителя(свойством модели родителя), ну думая о том, что на самом деле данные разнесены по разным таблицам.

Имеем полное право вычитать адресные данные пользователя:

User.address.find(:all)

street = User.find_by_id(id).address.street

пятница, 16 января 2009 г.

Перегенерить кеш для движка PHPFox

Недавно столкнулся с проблемой - как перегенерить весь кеш для сайта написаного на движке PHPFox?

Для того чтобы перегенерить весь кеш - необходимо удалить все содержимое папки кеша. Это бывает просто необходимым если вам надо задать другие значения константам для конфига которые хранятся в БД.

Например размер  максимально возможного для загрузки файла хранится в таблице phpfoxtest_sys_sett в переменной max_upload_size. Она в свою очередь доступна из приложения как App::getSetting('max_upload_size'). 

Именно для изминения значения этой константы мне и пришлось перегенерить весь кеш.

Для того чтобы довить новую переменную языка (тестовую константу которая имеет перевод на нужный язык) вам надо добавить ключ с переводами в таблицу phpfoxtest_language_phrase, а потом удалить файл languages_1.php в /file/cache/ 

CodeIgniter Partials

В контроллере Игнайтера создаем небольшой приватный метод:

private function template($data,$page='index'){
  $data['content'] = $this->load->view('controller_name/'.$page, $data, true);
  $data['menu'] = $this->load->view('shared/menu', array(), true);
  $this->load->view('shared/layout', $data);
 }
}

Мы собираем партиалы используя возможность метода load не только отображать страницу, но и сохранять ее в переменной если последним параметром передан TRUE.


Использовать метод нужно так:

function view()
{
  $data['title'] = $this->lang->line('title');
  $data['heading'] = $this->lang->line('heading');
  $this->template($data,'view');
}

Для того, чтобы достать партиалы в главном шаблоне нужно сделать так:


echo $content
echo $menu


Только надо вставить вызовы в нужное место cверстанного шаблона(вставка php кода в Html).

пятница, 9 января 2009 г.

Introduction to CodeIgniter

CodeIgniter - очень мощный и удобный ПХП фреймворк для создания веб-проектов. Постараюсь делится своими впечатлениями и расказывать о его возможностьях в последующих статьях, посвященных ему. 

Почему имеено CodeIgniter?

Мой любимый яык программирования безусловно только руби, но... программист должен писать на любом языке. Все же,  я хотел найти фреймворк для ПХП похожый на родные Релсы. Таковым на данный момент является CodeIgniter. 

Основные его особенности:
  • MVC архитектура и жесткая структура папок (точно так же как и в рельсах)
  • Встроен PHP аналог ActiveRecord, не такой мощный, это факт, но довольно удобный. При желании использовать что-то помощнее, не трудно подключит полноценный ORM - Doctrine.
  • Удобный роутер урлов( Аля-рельсы).
  • Удобное подключение БД.
  • Легкость настройки всех параметров фреймворка в одном месте (главный контролер, автозагрузка хелперов и т.д.)
  • Большой набор хелперов
  • Очень богатая и подробная ДОКУМЕНТАЦИЯ
  • Богатый набор компонентов и плагинов (например отличный пейдженатор).
  • Простое расширение функционала посредством установки компонент или расширения имеющихся
  • И самое главное для меня, все лежит почти там где и в рельсах, и по возможности реализованы особенности рельсов.
Но все же, ето далеко не Рельса... Сама мощь и красота руби делает рельсы рельсами. 

НИКОГДА Не забывайте ВЕЛИКОГО  НАСТАВНИКА, ибо он раскрывал и раскрывает новичкам и професионалам удивительный мир Ruby on Rails.

вторник, 2 декабря 2008 г.

Lorem Ipsum Dolor....

Именно такие строки часто являются началом контента для многих веб-страниц, это означает что они находятся еще в процессе разработки, почему так часто для тестового наполнения используется именно этот фрагмент латыни?

Дело в том, что для проверки шрифтов, отступов и т.д., то-есть правильности верстки, принято заполнять страницу большыми фрагментами текста. Это нужно для того чтобы посмотреть как будут вести себя дом-элементы содержащие текст в реальной работе. Использовать что-то типа: "...Тест Тест Тест Тест Тест Тест...." не есть правильно, так как нужно испоьзовать сбалансированый текст, с правильным распределением пробелов, знаков пунктуации, а также длины слов. Также замечено, что при таких проверках важно чтобы смысл текста не отвлекал тестера от работы. Идеальным текстом является Lorem Ipsum.

Lorem Ipsum - это текст-"рыба", часто используемый в печати и вэб-дизайне. Lorem Ipsum является стандартной "рыбой" для текстов на латинице с начала XVI века. В то время некий безымянный печатник создал большую коллекцию размеров и форм шрифтов, используя Lorem Ipsum для распечатки образцов. Lorem Ipsum не только успешно пережил без заметных изменений пять веков, но и перешагнул в электронный дизайн. Его популяризации в новое время послужили публикация листов Letraset с образцами Lorem Ipsum в 60-х годах и, в более недавнее время, программы электронной вёрстки типа Aldus PageMaker, в шаблонах которых используется Lorem Ipsum.

Привожу фрагмент текста из 5 абзацов, который можно использовать в работе:

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean sed lectus feugiat tortor tincidunt iaculis. Integer malesuada metus laoreet lectus. Donec dictum lobortis libero. Aenean nibh orci, ullamcorper eu, convallis ut, egestas quis, eros. Quisque pellentesque orci eu arcu. Proin urna nisi, accumsan sit amet, condimentum vel, ultricies ac, tellus. Integer fermentum, metus a feugiat vestibulum, urna eros lacinia urna, pulvinar blandit libero sem in neque. Etiam rhoncus. Sed urna. Aliquam consequat, nibh sit amet fringilla dapibus, urna tellus elementum quam, quis tristique quam velit et diam. Nam eget tellus vel tortor varius consequat. Aliquam auctor posuere mi. Pellentesque sit amet ipsum. Nam libero massa, venenatis vel, dapibus eget, lacinia a, erat.

Donec rhoncus sodales tellus. Vestibulum iaculis vehicula justo. Maecenas non dui in nunc egestas gravida. Cras mattis. Integer turpis mauris, pharetra id, feugiat a, elementum et, neque. Etiam purus. Mauris tincidunt, ipsum in sollicitudin consectetur, est nulla porttitor erat, sed blandit lorem erat eget dui. Curabitur ante lectus, mollis sit amet, auctor et, faucibus non, tellus. In commodo. Morbi nibh. Aenean eget sapien eu dolor porttitor auctor. Nullam elementum urna eget tellus. Mauris porta rutrum elit. Morbi eu tellus. In odio. Suspendisse potenti. Nam convallis lacus sit amet libero. Phasellus sem. Etiam augue mi, eleifend in, dapibus sed, ullamcorper vitae, orci.

Donec auctor, lacus et porta varius, lectus ligula ullamcorper augue, in faucibus libero turpis sed dolor. Nam vulputate tortor. Aliquam tempus ante ut tortor. Sed venenatis pretium purus. Curabitur rhoncus magna eget leo. Nunc blandit leo a dui. Etiam ut lectus sit amet turpis dictum luctus. Nunc sed neque non magna placerat placerat. Nam accumsan consequat nunc. Nulla viverra malesuada dui. Donec convallis ante vitae nulla. Duis placerat blandit nunc.

Suspendisse nunc velit, tincidunt eget, accumsan quis, placerat et, arcu. Aliquam erat volutpat. Aenean eu nulla. Donec dignissim, purus nec porta blandit, justo nunc blandit lectus, eu rutrum eros justo vel tortor. Nullam tortor nisl, cursus et, pellentesque ac, ornare ut, orci. Nunc leo. Suspendisse potenti. Pellentesque tristique, magna et porttitor vestibulum, ipsum dui egestas dui, eget accumsan erat ipsum id ante. Morbi ante purus, mollis et, tincidunt id, condimentum posuere, ante. Nulla ullamcorper bibendum metus. Integer ut diam. Donec ullamcorper orci. Sed porttitor, odio non porta faucibus, mi turpis aliquet nisl, vitae euismod dolor felis non eros. Quisque sit amet est sit amet dui ullamcorper lacinia. Aliquam tempus, magna sit amet lacinia lacinia, diam risus malesuada pede, et aliquam felis dui at nulla. Donec diam mi, sollicitudin nec, egestas eget, posuere in, nibh. Proin sit amet dui eget tellus blandit imperdiet. Nullam libero erat, ornare vel, lacinia quis, venenatis sit amet, massa. Sed leo enim, mattis sed, placerat id, venenatis eu, diam. Sed est.

Aliquam blandit. Cras sem. Aenean dictum mauris sit amet pede. Nam eu lectus. Mauris a nisl nec felis interdum pharetra. Maecenas non neque sed neque malesuada sagittis. Suspendisse potenti. Suspendisse condimentum pulvinar nisl. Nunc mi elit, facilisis sed, tempor ac, tincidunt ac, justo. Aliquam dui. Donec neque. Cras neque tortor, sagittis id, consequat sit amet, dapibus quis, magna. Pellentesque id metus ac diam accumsan ullamcorper. Nulla facilisi. Phasellus sit amet neque. Vivamus ac sapien. Sed faucibus urna vel sem. Ut ipsum.