Пуля — дура. Пых — молодец.

Добро пожаловать на Пыху!

Логин:
Пароль:
 

Нет прописки? Зарегистрируйся!

Новости

Пыха информатор 3.1
Еще более удобное оповещение о флуде!

Краснодарское время: 26 Май, 2012, 02:12:46

Страниц: [1]
Печать
Автор Тема: CRUD и генераторы скаффолдов  (Прочитано 4638 раз)
0 Пользователей и 1 Гость смотрят эту тему.
killich    ↓ 
23 Август, 2009, 11:19:37
НЕ ХУЕТА! ХУЕТА!

Группа: Санитары

Карма: 20
Сообщений: 275
Сила слова: 7.27

CRUD и генераторы скаффолдов
 
Начать данный пост хотелось бы со слов замечательного поэта:
 

 
Ночь, улица, фонарь, аптека,
Бессмысленный и тусклый свет.
Живи еще хоть четверть века -
Все будет так. Исхода нет.
 
Умрешь - начнешь опять сначала
И повторится все, как встарь:
Ночь, ледяная рябь канала,
Аптека, улица, фонарь.
 
Александр Блок.
10 октября 1912

CRUD — (англ. create read update delete — «Создание чтение обновление удаление») сокращенное именование 4 базовых функций управления данными — создание, чтение, редактирование и удаление.
 
http://ru.wikipedia.org/wiki/CRUD
 
Если вы повнимательней присмотритесь к своим приложениям, то наверняка сможете найти и у себя множество функций блоков кода, которые занимаются именно тем, что выполняют указанные действия над некоторой сущностью вашего проекта.
 
Например:
 
-Пост из вашего блога - создать, просматривать, редактировать, удалить.
 
-Альбом фотографий - создать , просматривать (увидеть все фото), редактировать, удалить.
 
-Фотография из альбома -  создать (загрузить), просматривать, редактировать, удалить.
 
-Страница (в дереве страниц) - создать, просматривать, редактировать, удалить, поднять вверх по дереву, поднять
вниз по дереву, перенести страницу и все дочерние в другой раздел.

 
Хм! Вы не поверите, но алгоритм создания, просмотра, редактирования, удаления - у всех объектов один и тот же.
 
Создание - получить данные для заполнения объекта, создать новую запись в таблице БД.
Просмотр - получить данные об объекте из БД по некоторому id, передать данные для отрисовки в шаблонизтор.
Редактировать - получить данные об объекте из БД по некоторому id, передать данные для отрисовки в шаблонизтор с формой редактирования.
Удалить - удалить объект из БД по id. Перенаправить пользователя на страницу со списком объектов.
 
Поскольку алгоритм действия для всех объектов одинаков - то не стоит тратить время для создания таких простых и однотипных операций - можно написать генератор кода, который по заданному имени объектов будут создавать сам создавать уже готовый код для управления объектами данного типа.
 
Кроме того, поскольку отображение списков объектов, форм редактирования, страниц просмотра в простейшем случае тоже очень похоже - то пожалуй ничего не стоит сделать программу, которая по по заданным именам полей и указанным типам данных будет сама создавать шаблоны для отрисовки.
 
Данная тема - давно отработана в rails - и существует несколько альтернатив по созданию кода для CRUD операций.
Скаффолды - Scaffolds (строительные леса, подмостки, то что помогает строить базовый административный интерфейс) -- общее имя генераторам которые занимаются формированием кода для CRUD операций
 
В среде rails есть свой стандартный генератор скаффолдов.
 
И так, я вызываю генератор скаффолдов:
 
Ruby
#ruby script/generate scaffold BlogPost title:string description:string content:text position:integer

Он по заданным параметрам создает
1. Миграцию:
Ruby
class CreateBlogPosts < ActiveRecord::Migration
  def self.up
    create_table :blog_posts do |t|
      t.string :title
      t.string :description
      t.text :content
      t.integer :position
 
      t.timestamps
    end
  end
 
  def self.down
    drop_table :blog_posts
  end
end

Выполнив миграцию - вы создадите в БД нужную таблицу для хранения данных об объектах данного класса.
 
Чувствуете?! В простейших случаях (а их большинство), Вы теперь можете забыть о средствах вроде: phpMyAdmin, работы в чистом сеансе sql, написания своих скриптов для изменений в БД.
 
2. Модель (программное представления об объектах БД в вашем приложении)
 
Ruby
class BlogPost < ActiveRecord::Base
  # тут пока пусто
  # это просто класс унаследованный от ActiveRecord::Base
end

3. Контроллер (бизнес логику приложения)
 
Ruby
class BlogPostsController < ApplicationController
  # GET /blog_posts
  # GET /blog_posts.xml
  def index
    @blog_posts = BlogPost.all
 
    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @blog_posts }
    end
  end
 
  # GET /blog_posts/1
  # GET /blog_posts/1.xml
  def show
    @blog_post = BlogPost.find(params[:id])
 
    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @blog_post }
    end
  end
 
  # GET /blog_posts/new
  # GET /blog_posts/new.xml
  def new
    @blog_post = BlogPost.new
 
    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @blog_post }
    end
  end
 
  # GET /blog_posts/1/edit
  def edit
    @blog_post = BlogPost.find(params[:id])
  end
 
  # POST /blog_posts
  # POST /blog_posts.xml
  def create
    @blog_post = BlogPost.new(params[:blog_post])
 
    respond_to do |format|
      if @blog_post.save
        flash[:notice] = 'BlogPost was successfully created.'
        format.html { redirect_to(@blog_post) }
        format.xml  { render :xml => @blog_post, :status => :created, :location => @blog_post }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @blog_post.errors, :status => :unprocessable_entity }
      end
    end
  end
 
  # PUT /blog_posts/1
  # PUT /blog_posts/1.xml
  def update
    @blog_post = BlogPost.find(params[:id])
 
    respond_to do |format|
      if @blog_post.update_attributes(params[:blog_post])
        flash[:notice] = 'BlogPost was successfully updated.'
        format.html { redirect_to(@blog_post) }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @blog_post.errors, :status => :unprocessable_entity }
      end
    end
  end
 
  # DELETE /blog_posts/1
  # DELETE /blog_posts/1.xml
  def destroy
    @blog_post = BlogPost.find(params[:id])
    @blog_post.destroy
 
    respond_to do |format|
      format.html { redirect_to(blog_posts_url) }
      format.xml  { head :ok }
    end
  end
end

4. Шаблоны для отрисовки данных и форм (Вид)
 
index.html.erb
 
Ruby

<h1>Listing blog_posts</h1>
 
<table>
  <tr>
    <th>Title</th>
    <th>Description</th>
    <th>Content</th>
    <th>Position</th>
  </tr>
 
<% @blog_posts.each do |blog_post| %>
  <tr>
    <td><%=h blog_post.title %></td>
    <td><%=h blog_post.description %></td>
    <td><%=h blog_post.content %></td>
    <td><%=h blog_post.position %></td>
    <td><%= link_to 'Show', blog_post %></td>
    <td><%= link_to 'Edit', edit_blog_post_path(blog_post) %></td>
    <td><%= link_to 'Destroy', blog_post, :confirm => 'Are you sure?', :method => :delete %></td>
  </tr>
<% end %>
</table>
 
<br />
 
<%= link_to 'New blog_post', new_blog_post_path %>

 
edit.html.erb
Ruby

<h1>Editing blog_post</h1>
 
<% form_for(@blog_post) do |f| %>
  <%= f.error_messages %>
 
  <p>
    <%= f.label :title %><br />
    <%= f.text_field :title %>
  </p>
  <p>
    <%= f.label :description %><br />
    <%= f.text_field :description %>
  </p>
  <p>
    <%= f.label :content %><br />
    <%= f.text_area :content %>
  </p>
  <p>
    <%= f.label :position %><br />
    <%= f.text_field :position %>
  </p>
  <p>
    <%= f.submit 'Update' %>
  </p>
<% end %>
 
<%= link_to 'Show', @blog_post %> |
<%= link_to 'Back', blog_posts_path %>
 
 

 
new.html.erb
 
Ruby
<h1>New blog_post</h1>
 
<% form_for(@blog_post) do |f| %>
  <%= f.error_messages %>
 
  <p>
    <%= f.label :title %><br />
    <%= f.text_field :title %>
  </p>
  <p>
    <%= f.label :description %><br />
    <%= f.text_field :description %>
  </p>
  <p>
    <%= f.label :content %><br />
    <%= f.text_area :content %>
  </p>
  <p>
    <%= f.label :position %><br />
    <%= f.text_field :position %>
  </p>
  <p>
    <%= f.submit 'Create' %>
  </p>
<% end %>
 
<%= link_to 'Back', blog_posts_path %>

show.html.erb
 
Ruby
<p>
  <b>Title:</b>
  <%=h @blog_post.title %>
</p>
 
<p>
  <b>Description:</b>
  <%=h @blog_post.description %>
</p>
 
<p>
  <b>Content:</b>
  <%=h @blog_post.content %>
</p>
 
<p>
  <b>Position:</b>
  <%=h @blog_post.position %>
</p>
 

<%= link_to 'Edit', edit_blog_post_path(@blog_post) %> |
<%= link_to 'Back', blog_posts_path %>

Поскольку я работаю с HAML - то я не поленился и написал свои простейшие скаффолды с формированием HAML шаблонов отображения.
 
Видео уроки формата Блог на Rails за 15 минут основаны на технике скаффолдов.
Такие же средства, как мне известно есть на большинстве современных платформ, типа django on pyhton.
 

С уважением к php сообществу, Илья Зыкин, Иваново 2009.
« Последнее редактирование: 23 Август, 2009, 11:18:46 от killich » Записан
Sinkler    ↓ 
23 Август, 2009, 11:00:44 , спустя
НЕ ХУЕТА! ХУЕТА!

Похуй, пляшем!
Группа: Джедаи

Карма: 73
Сообщений: 6811
Сила слова: 1.07

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

killich    ↓ 
23 Август, 2009, 11:17:39 , спустя 16 минут 55 секунд
НЕ ХУЕТА! ХУЕТА!

Группа: Санитары

Карма: 20
Сообщений: 275
Сила слова: 7.27

cakePHP -- rails клон.
не представляю, смог бы я найти в себе силы разобраться в нем или нет..
то что ты смог - уважаю! круто!
 
Думаю большинство моих постов для тебя не новость.
Записан
Sinkler    ↓ 
23 Август, 2009, 11:47:57 , спустя 30 минут 18 секунд
НЕ ХУЕТА! ХУЕТА!

Похуй, пляшем!
Группа: Джедаи

Карма: 73
Сообщений: 6811
Сила слова: 1.07


cakePHP -- rails клон.
не представляю, смог бы я найти в себе силы разобраться в нем или нет..
то что ты смог - уважаю! круто!
 
Думаю большинство моих постов для тебя не новость.

В кейке нет ничего сложного. Единственная сложность - очень мало информации и материалов о нем в рунете. Еще его большой недостаток - приходится тщательно оптимизировать код и запросы к бд, т.к. он довольно медлительный (кстати, в версии 2.0 будет прирост производительности из-за отказа подержки пхп4, версия 3.0 будет полностью переписана на пхп5.3).
 
Да, твои статьи мне знакомы и понятны, только они про руби, а так как ты объясняешь ну просто суперски (сразу видно - учитель), то их изучение помогает мне  закрепить и глубже понять  принципы работы мвц-фреймворков вобще. Плюс сравниваю руби и кейк, возможно, в будущем попробую поработать в руби, хотя пока не вижу преимуществ перед кейком (возможно, ты поможешь их увидеть).
Записан

killich    ↓ 
23 Август, 2009, 12:14:16 , спустя 26 минут 19 секунд
НЕ ХУЕТА! ХУЕТА!

Группа: Санитары

Карма: 20
Сообщений: 275
Сила слова: 7.27

Спасибо за добрые слова.
 
Очень важная часть дающая rails плюс - это обращение к БД. Я работаю с библиотекой ActiveRecord - просто она встроена в rails - и наиболее широко известна.
Для php разработчика аналогом может быть Доктрина http://www.doctrine-project.org/
 
Один мой знакомый удачно сочетает Доктрину и cakePHP
Так же как я понимаю - удачна связка Symfony и Doctrine
 
В любом случае - использование фреймворка это уже признак качества разрабатываемого продукта и показывает уровень профессиональной зрелости.
Следующим шагом является использование системы контроля версии. SVN или GIT
 
Однажды просто дойдешь до того состояния, что станешь настолько крутым - что много кода писать станет в лом - и вот тогда будешь искать язык с минималистическим оформлением - типа руби или питона - где люди не пишут круглых скобок в именах функций или не ставят ничего не значащих точек с запятой в конце строки кода.
 
Вот например как в руби рельсах записываются величины объема информации:
 
Ruby
1.kilobyte
3.kilobytes
3.megabytes + 50.kilobytes
3.gigabytes

Или временные значения
 
Ruby
1.day.ago
3.days.from_now
3.days.from_now + 3.hours + 5.minutes

Все в руби объект и числа - 1, 3, 15 - все это экземпляры класса Fixnum внутри которого определены соответствующие методы - упрощающие жизнь программисту.
 
Я никогда не утверждаю, что такого нельзя сделать в другом языке - конечно можно. Однако, не всегда это бывает так же элегантно и удобочитаемо.
Записан
DarkMist    ↓ 
28 Февраль, 2011, 02:24:44 , спустя 554 дня 3 часа 10 минут 28 секунд
НЕ ХУЕТА! ХУЕТА!

Карма: 0
Сообщений: 3
Сила слова: 0

отличный пост, побольше бы таких!!
Записан
Страниц: [1]
Печать
 

Перейти в:  

Этот топик скрыли: adw0rd