O post de hoje vai falar de um plugin que resolve um problema
relativamente simples, porém muito comum, o que faz do
FileColumn uma ferramenta extremamente útil.
Como sempre, vamos iniciar nosso projeto. No nosso exemplo, teremos
um modelo chamado 'Car', e ao cadastrar um carro pelo sistema,
também teremos a opção de incluir uma foto.
rails carstore
cd carstore
rake db:create:all
Ok, já temos nosso projeto. Vamos entao criar um scaffold simples para
gerenciamento dos carros que iremos 'vender'.
script/generate scaffold car brand:string model:string year:integer
Uma vez criado o scaffold, precisamos de uma migration adicional para
adicionar no banco de dados o campo que vai conter o nome do aquivo
de foto que vai ser incluída no anuncio do carro.
script/generate migration add_picture_to_cars
Edite o arquivo do migrations para adicionar o campo tipo string:
class AddPictureToCars < ActiveRecord::Migration
def self.up
add_column :cars, :picture, :string
end
def self.down
remove_column :cars, :picture
end
end
E, para nao esquecer, vamos rodar os migrations para garantir que
a tabela seja criada no banco de dados.
rake db:migrate
Muito bem. Nosso ambiente esta pronto para instalarmos o plugin.
script/plugin install http://opensvn.csie.org/rails_file_column/plugins/file_column/trunk
Uma vez que temos o plugin instalado, devemos informar na classe model 'Car' que
temos um campo que se trata na verdade de um upload de arquivo.
app/model/car.rb
class Car < ActiveRecord::Base
file_column :picture
end
Isso ja basta na nossa classe model. Agora precisamos trabalhar com nossos templates
para criar o campo de upload e visualização da imagem:
Formulário para novo anúncio:
app/views/cars/new.html.erb
<h1>New car</h1>
<% form_for(@car, :html => { :multipart => true }) do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :brand %><br />
<%= f.text_field :brand %>
</p>
<p>
<%= f.label :model %><br />
<%= f.text_field :model %>
</p>
<p>i
<%= f.label :year %><br />
<%= f.text_field :year %>
</p>
<p>
<%= f.label :picture %><br/>
<%= file_column_field 'car', 'picture' %>
</p>
<p>
<%= f.submit "Create" %>
</p>
<% end %>
<%= link_to 'Back', cars_path %>
Uma coisa muito importante que deve ser observada neste codigo é
a parte que torna o formulário um form do tipo multipart, caso
contrário o upload nã irá funcionar.
Formulario para editar anuncio:
app/views/cars/edit.html.erb
<h1>Editing car</h1>
<% form_for(@car, :html => { :multipart => true }) do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :brand %><br />
<%= f.text_field :brand %>
</p>
<p>
<%= f.label :model %><br />
<%= f.text_field :model %>
</p>
<p>
<%= f.label :year %><br />
<%= f.text_field :year %>
</p>
<p>
<%= f.label :picture %><br/>
<% unless @car.picture.blank? %>
<%= image_tag url_for_file_column('car', 'picture') %>
<br/>
<% end %>
<%= file_column_field 'car', 'picture' %>
<p>
<%= f.submit "Update" %>
</p>
<% end %>
<%= link_to 'Show', @car %> |
<%= link_to 'Back', cars_path %>
Uma coisa importante a notar neste segundo formulario é que
quando já existe uma foto no sistema o usuá pode visualizá-la.
E, por fim, vamos editar a página de visualização do anúncio:
app/views/cars/show.html.erb
<p>
<b>Brand:</b>
<%=h @car.brand %>
</p>
<p>
<b>Model:</b>
<%=h @car.model %>
</p>
<p>
<b>Picture:</b><br/>
<%= image_tag url_for_file_column(:car, :picture) %>
</p>
<p>
<b>Year:</b>
<%=h @car.year %>
</p>
<%= link_to 'Edit', edit_car_path(@car) %> |
<%= link_to 'Back', cars_path %>
Depois é só subir o server e curtir!
quinta-feira, 16 de outubro de 2008
sexta-feira, 10 de outubro de 2008
Paginação fácil em Rails com Will Paginate
Sim, é claro que você já precisou paginar resultados na sua aplicação web. No nosso post de hoje, vou falar do Will Paginate, um ótima biblioteca para fazer isso em Rails.
Como de costume, vamos criar um novo projeto (listagem de tarefas):
rails mytasks
cd mytasks
rake db:create:all
Muito bem, vamos então preparar nosso model e nosso controller com 2 metodos apenas. Um para listar as tasks e um para criar tasks virtuais pra nós - Não vou cobrir todas as etapas CRUD aqui pois este não é o foco e imagino que nem precisemos disto.
script/generate model task title:string description:text
rake db:migrate
script/generate controller tasks index generate
Com nosso controller criado, vamos implementar os dois metodos reponsáveis por nossas actions. A primeira vai simplesmente listar as tasks, enquanto a segunda vai criar registros de tasks no banco (e, claro, remover as existentes também)
app/controllers/tasks_controller.rb
class TasksController < ApplicationController
def index
@tasks = Task.find(:all)
end
def generate
Task.delete_all
50.times do |i|
task = Task.create(:title => "Task number #{i}", :description => "Description for task number #{i}")
end
flash[:notice] = "50 fresh new tasks created!"
redirect_to :action => 'index'
end
end
Ok, nosso controller esta preparado para o iní do nosso propósito. vamos entao deixar os templates preparados tambem.
app/views/tasks/index.html.erb
<h1>My Tasks</h1>
<% if flash[:notice] %>
<h3><%= flash[:notice] %></h3>
<% end %>
<% for task in @tasks %>
<p>
<b><%= task.title %></b><br/>
<i><%= task.description %></i>
</p>
<% end %>
Nao precisamos do view do generate, claro:
rm app/views/tasks/generate.html.erb
Vamos entao iniciar nosso server para ter certeza que tudo esta ok ate aqui:
script/server
Accesse diretamente o metodo para criar as tasks em seu controller:
http://localhost:3000/tasks/generate
Ok, ja temos nossas tasks, e nossa página principal para listá-las. O único problema, claro, é que precisamos de uma paginação.
Para começar, precisamos instalar a biblioteca, que na verdade está disponibilizado na forma de uma ruby gem. Vamos então usar o gem install. Adicione o GitHub no seu gem sources se você ainda nao tiver:
gem sources -a http://gems.github.com
Instale a biblioteca:
(sudo) gem install mislav-will_paginate
A instalação de uma gem é um pouco diferente da de um plugin. No nosso caso, precisamos agora adicionar a chamada &acrave; nossa biblioteca no nosso environment.rb:
config/environment.rb
Rails::Initializer.run do |config|
...
end
require "will_paginate"
Reinicie o seu servidor para que as alterações tenham efeito.
Agora precisamos alterar nosso controller, para adaptar o paginate &acrave; nossa lista de tasks:
app/controllers/tasks_controller.rb
def index
#@tasks = Task.find(:all) - podemos remover esta linha
@tasks = Task.paginate :page => params[:page], :per_page => 20
end
Visualize sua pagina no browser, para ver que agora so temos 20 resultados na pagina. Precisamos então conseguir acessar as outras páginas... o que é, como sempre, é uma tarefa muito fácil:
app/views/tasks/index.html.erb
<h1>My Tasks</h1>
<% if flash[:notice] %>
<h3><%= flash[:notice] %></h3>
<% end %>
<% for task in @tasks %>
<p>
<b><%= task.title %></b><br/>
<i><%= task.description %></i>
</p>
<% end %>
<%= will_paginate @tasks %>
Bom, eu avisei que era fácil!
Mas e Filtros, Orders e etc?
Sim, o Will Paginate também cobre problemas comuns como estes. Na verdade, a nossa biblioteca funciona tão bem como o find do ActiveRecord, permitindo brincadeiras como esta:
@products = Product.paginate_by_category_id @category.id, :page => params[:page], :order => 'price'
Chegamos ao fim de mais um post sobre bibliotecas e plugins rails. Espero que tenha sido util!
Até a próxima!
Como de costume, vamos criar um novo projeto (listagem de tarefas):
rails mytasks
cd mytasks
rake db:create:all
Muito bem, vamos então preparar nosso model e nosso controller com 2 metodos apenas. Um para listar as tasks e um para criar tasks virtuais pra nós - Não vou cobrir todas as etapas CRUD aqui pois este não é o foco e imagino que nem precisemos disto.
script/generate model task title:string description:text
rake db:migrate
script/generate controller tasks index generate
Com nosso controller criado, vamos implementar os dois metodos reponsáveis por nossas actions. A primeira vai simplesmente listar as tasks, enquanto a segunda vai criar registros de tasks no banco (e, claro, remover as existentes também)
app/controllers/tasks_controller.rb
class TasksController < ApplicationController
def index
@tasks = Task.find(:all)
end
def generate
Task.delete_all
50.times do |i|
task = Task.create(:title => "Task number #{i}", :description => "Description for task number #{i}")
end
flash[:notice] = "50 fresh new tasks created!"
redirect_to :action => 'index'
end
end
Ok, nosso controller esta preparado para o iní do nosso propósito. vamos entao deixar os templates preparados tambem.
app/views/tasks/index.html.erb
<h1>My Tasks</h1>
<% if flash[:notice] %>
<h3><%= flash[:notice] %></h3>
<% end %>
<% for task in @tasks %>
<p>
<b><%= task.title %></b><br/>
<i><%= task.description %></i>
</p>
<% end %>
Nao precisamos do view do generate, claro:
rm app/views/tasks/generate.html.erb
Vamos entao iniciar nosso server para ter certeza que tudo esta ok ate aqui:
script/server
Accesse diretamente o metodo para criar as tasks em seu controller:
http://localhost:3000/tasks/generate
Ok, ja temos nossas tasks, e nossa página principal para listá-las. O único problema, claro, é que precisamos de uma paginação.
Para começar, precisamos instalar a biblioteca, que na verdade está disponibilizado na forma de uma ruby gem. Vamos então usar o gem install. Adicione o GitHub no seu gem sources se você ainda nao tiver:
gem sources -a http://gems.github.com
Instale a biblioteca:
(sudo) gem install mislav-will_paginate
A instalação de uma gem é um pouco diferente da de um plugin. No nosso caso, precisamos agora adicionar a chamada &acrave; nossa biblioteca no nosso environment.rb:
config/environment.rb
Rails::Initializer.run do |config|
...
end
require "will_paginate"
Reinicie o seu servidor para que as alterações tenham efeito.
Agora precisamos alterar nosso controller, para adaptar o paginate &acrave; nossa lista de tasks:
app/controllers/tasks_controller.rb
def index
#@tasks = Task.find(:all) - podemos remover esta linha
@tasks = Task.paginate :page => params[:page], :per_page => 20
end
Visualize sua pagina no browser, para ver que agora so temos 20 resultados na pagina. Precisamos então conseguir acessar as outras páginas... o que é, como sempre, é uma tarefa muito fácil:
app/views/tasks/index.html.erb
<h1>My Tasks</h1>
<% if flash[:notice] %>
<h3><%= flash[:notice] %></h3>
<% end %>
<% for task in @tasks %>
<p>
<b><%= task.title %></b><br/>
<i><%= task.description %></i>
</p>
<% end %>
<%= will_paginate @tasks %>
Bom, eu avisei que era fácil!
Mas e Filtros, Orders e etc?
Sim, o Will Paginate também cobre problemas comuns como estes. Na verdade, a nossa biblioteca funciona tão bem como o find do ActiveRecord, permitindo brincadeiras como esta:
@products = Product.paginate_by_category_id @category.id, :page => params[:page], :order => 'price'
Chegamos ao fim de mais um post sobre bibliotecas e plugins rails. Espero que tenha sido util!
Até a próxima!
segunda-feira, 6 de outubro de 2008
Busca em Textos com Sphinx
Sphinx eh um otimo servidor de busca em texto. Hoje vou demonstrar
como voce pode ter um site com um engine de busca rodando em sphinx
atraves de um plugin em Rails.
Para iniciar, precisamos instalar o Sphinx. Basta seguir os passos
a seguir:
wget http://sphinxsearch.com/downloads/sphinx-0.9.8.tar.gz
tar xvzf sphinx-0.9.8.tar.gz
cd sphinx-0.9.8/
./configure
make
(sudo) make install
Uma vez com o sphinx instalado, va para a sua area de trabalho e crie
o projeto.
IMPORTANTE: O Sphinx nao funciona com sqlite, entao precisamos alterar
nosso databases.yml para funcionar com o Mysql.
rails mysite
cd mysite
Edite o seu databases.yml:
config/databases.yml
development:
adapter: mysql
database: mysite_dev
username: root
password:
test:
adapter: mysql
database: mysite_test
username: root
password:
Vamos criar os bancos!
rake db:create:all
Finalmente, instale o plugin:
script/plugin install git://github.com/freelancing-god/thinking-sphinx.git
Com o plugin instalado e funcionando, vamos criar um scaffold padrao. No
nosso caso, nosso projeto sera um website simples, com paginas gerenciadas em
um CMS e com busca por conteudo dentro das paginas. (Poderiamos inclusive utilizar
o projeto anterior que funciona com FCKEditor)
script/generate scaffold page title:string body:text published:boolean
Nao vamos esquecer de migrar a versao do banco, para que nosso schema seja
criado para a tabela pages.
rake db:migrate
E vamos criar um controller separado que ira conter nossa pagina inicial com
o campo de busca.
script/generate controller main index
E nao podemos esquecer de definir em nosso routes.rb que este eh nosso controller
root (padrao) em nosso projeto
config/routes.rb
map.root :controller => 'main'
Por ultimo, vamos remover o arquivo index.html
rm public/index.html
Inicie o server do seu projeto:
script/server
Ok, estamos quase prontos para comecar a instalar nossa busca. O que precisamos agora,
claro, eh criar algumas paginas. Vou deixar isso por sua conta. Siga para o proximo
passo quando tiver umas 4, 5 paginas criadas.
... criando paginas ... :-)
Se vc ja critou suas paginas, entao agora eh hora de colocar nosso plugin pra funcionar.
Vamos comecar pela parte facil, que eh justamente adicionar o campo de busca na nossa action principal, index, dentro do nosso controller principal, MainController:
app/views/main/index.html.erb
<h1>Main page</h1>
<%= form_tag %>
<%= text_field_tag :query %>
<%= submit_tag 'Search' %>
<hr/>
<% if @pages %>
<h3> Sua busca por '<%= @query %>' retornou <%= @pages.size %> resultados:</h3>
<ol>
<% for page in @pages %>
<li><%= link_to page.title, :controller => 'pages', :action => 'show', :id => page.id %></li>
<% end %>
</ol>
<% else %>
<h3> Sua busca por '<%= @query %>' nao retornou nenhum resultado</h3>
<% end %>
</form>
Ok, tudo indica que nosso View ja esta completo. Agora precisamos cuidar do controller.
Mas antes, precisamos identificar no nosso Model (Page) quais os campos que vao ser
indexaveis pela busca (e, consequentemente, buscaveis por ela)
No nosso caso, eh interessante indexar 2 campos do nosso modelo Page: title e body.
Para isto, basta adicionar o bloco define_index na sua classe:
app/models/page.rb
class Page < ActiveRecord::Base
define_index do
indexes title
indexes body
end
end
Muito bem. Model e View estao prontos. Agora precisamos cuidar do controller, que
sinceramente eh o mais facil de todos:
app/controllers/main_controller.rb
class MainController < ApplicationController
def index
@pages = Page.search params[:query]
@query = params[:query]
end
end
Agora que temos nosso plugin instalado, e o controller pronto, precisamos indexar
o conteudo de pages no sphinx, e depois iniciar seu server.
Para isto, temos 2 Rake tasks:
rake thinking_sphinx:index
rake thinking_sphinx:start
Ou, se voce preferir, tambem temos as mesmas rake tasks com um nome um pouco mais
curto:
rake ts:in
rake ts:start
IMPORTANTE: Sempre que uma pagina for alterada ou incluida no banco de dados, precisamos
rodar novamente o index do Sphinx. Podemos no futuro discutir uma forma de realizar isto
de uma forma periodica dentro do rails. Por hora, talvez seja interessante executar como
uma tarefa no crontab.
Inicie o server:
script/server
Agora eh so comecar a utilizar sua busca. No proximo post vou demonstrar como adicionar
paginacao nos resultados com um plugin de paginacao bem popular para Rails.
como voce pode ter um site com um engine de busca rodando em sphinx
atraves de um plugin em Rails.
Para iniciar, precisamos instalar o Sphinx. Basta seguir os passos
a seguir:
wget http://sphinxsearch.com/downloads/sphinx-0.9.8.tar.gz
tar xvzf sphinx-0.9.8.tar.gz
cd sphinx-0.9.8/
./configure
make
(sudo) make install
Uma vez com o sphinx instalado, va para a sua area de trabalho e crie
o projeto.
IMPORTANTE: O Sphinx nao funciona com sqlite, entao precisamos alterar
nosso databases.yml para funcionar com o Mysql.
rails mysite
cd mysite
Edite o seu databases.yml:
config/databases.yml
development:
adapter: mysql
database: mysite_dev
username: root
password:
test:
adapter: mysql
database: mysite_test
username: root
password:
Vamos criar os bancos!
rake db:create:all
Finalmente, instale o plugin:
script/plugin install git://github.com/freelancing-god/thinking-sphinx.git
Com o plugin instalado e funcionando, vamos criar um scaffold padrao. No
nosso caso, nosso projeto sera um website simples, com paginas gerenciadas em
um CMS e com busca por conteudo dentro das paginas. (Poderiamos inclusive utilizar
o projeto anterior que funciona com FCKEditor)
script/generate scaffold page title:string body:text published:boolean
Nao vamos esquecer de migrar a versao do banco, para que nosso schema seja
criado para a tabela pages.
rake db:migrate
E vamos criar um controller separado que ira conter nossa pagina inicial com
o campo de busca.
script/generate controller main index
E nao podemos esquecer de definir em nosso routes.rb que este eh nosso controller
root (padrao) em nosso projeto
config/routes.rb
map.root :controller => 'main'
Por ultimo, vamos remover o arquivo index.html
rm public/index.html
Inicie o server do seu projeto:
script/server
Ok, estamos quase prontos para comecar a instalar nossa busca. O que precisamos agora,
claro, eh criar algumas paginas. Vou deixar isso por sua conta. Siga para o proximo
passo quando tiver umas 4, 5 paginas criadas.
... criando paginas ... :-)
Se vc ja critou suas paginas, entao agora eh hora de colocar nosso plugin pra funcionar.
Vamos comecar pela parte facil, que eh justamente adicionar o campo de busca na nossa action principal, index, dentro do nosso controller principal, MainController:
app/views/main/index.html.erb
<h1>Main page</h1>
<%= form_tag %>
<%= text_field_tag :query %>
<%= submit_tag 'Search' %>
<hr/>
<% if @pages %>
<h3> Sua busca por '<%= @query %>' retornou <%= @pages.size %> resultados:</h3>
<ol>
<% for page in @pages %>
<li><%= link_to page.title, :controller => 'pages', :action => 'show', :id => page.id %></li>
<% end %>
</ol>
<% else %>
<h3> Sua busca por '<%= @query %>' nao retornou nenhum resultado</h3>
<% end %>
</form>
Ok, tudo indica que nosso View ja esta completo. Agora precisamos cuidar do controller.
Mas antes, precisamos identificar no nosso Model (Page) quais os campos que vao ser
indexaveis pela busca (e, consequentemente, buscaveis por ela)
No nosso caso, eh interessante indexar 2 campos do nosso modelo Page: title e body.
Para isto, basta adicionar o bloco define_index na sua classe:
app/models/page.rb
class Page < ActiveRecord::Base
define_index do
indexes title
indexes body
end
end
Muito bem. Model e View estao prontos. Agora precisamos cuidar do controller, que
sinceramente eh o mais facil de todos:
app/controllers/main_controller.rb
class MainController < ApplicationController
def index
@pages = Page.search params[:query]
@query = params[:query]
end
end
Agora que temos nosso plugin instalado, e o controller pronto, precisamos indexar
o conteudo de pages no sphinx, e depois iniciar seu server.
Para isto, temos 2 Rake tasks:
rake thinking_sphinx:index
rake thinking_sphinx:start
Ou, se voce preferir, tambem temos as mesmas rake tasks com um nome um pouco mais
curto:
rake ts:in
rake ts:start
IMPORTANTE: Sempre que uma pagina for alterada ou incluida no banco de dados, precisamos
rodar novamente o index do Sphinx. Podemos no futuro discutir uma forma de realizar isto
de uma forma periodica dentro do rails. Por hora, talvez seja interessante executar como
uma tarefa no crontab.
Inicie o server:
script/server
Agora eh so comecar a utilizar sua busca. No proximo post vou demonstrar como adicionar
paginacao nos resultados com um plugin de paginacao bem popular para Rails.
sexta-feira, 3 de outubro de 2008
Instalando o FCKEditor: Um Otimo Editor HTML / WYSIWYG
O FCKEditor é, na minha opinião, o melhor editor html (WYSIWYG) da atualidade. Com funcionalidades como 'Paste from Word' e Upload de imagens, o editor nunca deixou a desejar.
Hoje vou explicar como instalar este editor no seu projeto Rails, utilizando um plugin. A pagina do plugin, para quem quiser mais informações, esta disponivel aqui.
Como exemplo desta vez, vamos criar um pequeno projeto para Blog Posts que vai utilizar o FCKEditor para o corpo da postagem. Não se esqueça de checar seu databases.yml se precisar de mudanças.
rails myblog
cd myblog
rake db:create
Vamos criar um scaffold padrao para nossos posts:
ruby script/generate scaffold post title:string content:text published:boolean
Para ja garantir que nosso scaffold funcione logo no começo, vamos remover a index.html do diretorio public e editar o routes.rb para apontar para nosso PostsController por padrão:
rm public/index.html
config/routes.rb
map.root :controller => "posts"
Vamos então migrar o banco para a ultima versão e iniciar o server, para ter certeza que esta tudo ok!
rake db:migrate
ruby script/server
Abra o projeto em seu navegador e crie uns posts. Vou assumir que isto já funciona a partir de agora.
Para instalar o plugin do FCKEditor, basta rodar o script de instalação de plugins em seu projeto:
ruby script/plugin install svn://rubyforge.org//var/svn/fckeditorp/trunk/fckeditor
Uma vez instalado, o plugin vai disponibilizar uma nova task rake, para que ele possa se auto instalar em diretorios como public/javascripts. Para confirmar que a nova rake task está disponível, execute o comando que mostra a lista de rake tasks:
rake -T
Confirme que você tem as tasks do fckeditor (rake fckeditor:download, fckeditor:install). Se estiver tudo ok, basta rodar a tarefa de instalação:
rake fckeditor:install
Otimo! O plugin já está instalado e pronto para uso. Agora precisamos adicionar o javascript do fckeditor nas nossas chamadas a javascript, no header do nosso layout.
app/view/layouts/posts.html.erb
span ><meta equiv="content-type" content="text/html;charset=UTF-8">
<title>Posts: <%= controller.action_name ></title>
<span > <%= stylesheet_link_tag 'scaffold' %></span>
<span > <%= javascript_include_tag 'fckeditor/fckeditor' %></span>
Muito bem. Agora basta trocarmos nossos campos de textarea pelo editor. No nosso exemplo, ja que geramos o scaffold automaticamente, temos 2 arquivos de template para fazer esta modificação: app/views/posts/new.html.erb e app/views/posts/edit.html.erb.
Primeiro o formulario para criar novos posts:
app/views/posts/new.html.erb
<% form_for(@post) do |f| %>
<%= f.error_messages %>
# remover esta linha que cria o textarea <%= f.text_area :content %>
<%= f.label :published %>
<%= f.check_box :published %>
<%= f.submit "Create" %>
<% end %>
<%= link_to 'Back', posts_path %>
Agora nosso formulario para editar posts existentes:
app/views/posts/edit.html.erb
<% form_for(@post) do |f| %>
<%= f.error_messages %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.check_box :published %>
<%= f.submit "Update" %>
<% end %>
<%= link_to 'Show', @post %> |
<%= link_to 'Back', posts_path %>
Agora, reinicie seu servidor para que ele detecte o novo plugin instalado, e crie seus blogs em formato HTML!
Extra: Para usar o FCKEditor com AJAX, basta utilizar a tag da seguinte forma:
<%= form_remote_tag :url => { :action => 'update', :id => @post }, :before => fckeditor_before_js('post', 'content') %>">
É isso aí. Até a próxima!
Hoje vou explicar como instalar este editor no seu projeto Rails, utilizando um plugin. A pagina do plugin, para quem quiser mais informações, esta disponivel aqui.
Como exemplo desta vez, vamos criar um pequeno projeto para Blog Posts que vai utilizar o FCKEditor para o corpo da postagem. Não se esqueça de checar seu databases.yml se precisar de mudanças.
rails myblog
cd myblog
rake db:create
Vamos criar um scaffold padrao para nossos posts:
ruby script/generate scaffold post title:string content:text published:boolean
Para ja garantir que nosso scaffold funcione logo no começo, vamos remover a index.html do diretorio public e editar o routes.rb para apontar para nosso PostsController por padrão:
rm public/index.html
config/routes.rb
map.root :controller => "posts"
Vamos então migrar o banco para a ultima versão e iniciar o server, para ter certeza que esta tudo ok!
rake db:migrate
ruby script/server
Abra o projeto em seu navegador e crie uns posts. Vou assumir que isto já funciona a partir de agora.
Para instalar o plugin do FCKEditor, basta rodar o script de instalação de plugins em seu projeto:
ruby script/plugin install svn://rubyforge.org//var/svn/fckeditorp/trunk/fckeditor
Uma vez instalado, o plugin vai disponibilizar uma nova task rake, para que ele possa se auto instalar em diretorios como public/javascripts. Para confirmar que a nova rake task está disponível, execute o comando que mostra a lista de rake tasks:
rake -T
Confirme que você tem as tasks do fckeditor (rake fckeditor:download, fckeditor:install). Se estiver tudo ok, basta rodar a tarefa de instalação:
rake fckeditor:install
Otimo! O plugin já está instalado e pronto para uso. Agora precisamos adicionar o javascript do fckeditor nas nossas chamadas a javascript, no header do nosso layout.
app/view/layouts/posts.html.erb
span ><meta equiv="content-type" content="text/html;charset=UTF-8">
<title>Posts: <%= controller.action_name ></title>
<span > <%= stylesheet_link_tag 'scaffold' %></span>
<span > <%= javascript_include_tag 'fckeditor/fckeditor' %></span>
Muito bem. Agora basta trocarmos nossos campos de textarea pelo editor. No nosso exemplo, ja que geramos o scaffold automaticamente, temos 2 arquivos de template para fazer esta modificação: app/views/posts/new.html.erb e app/views/posts/edit.html.erb.
Primeiro o formulario para criar novos posts:
app/views/posts/new.html.erb
<% form_for(@post) do |f| %>
<%= f.error_messages %>
<%= f.label :title %>
<%= f.text_field :title %>
# remover esta linha que cria o textarea <%= f.text_area :content %>
">
<%= fckeditor_textarea( :post, :content, :width => 600, :height => 400 ) %>
<%= fckeditor_textarea( :post, :content, :width => 600, :height => 400 ) %>
<%= f.label :published %>
<%= f.check_box :published %>
<%= f.submit "Create" %>
<% end %>
<%= link_to 'Back', posts_path %>
Agora nosso formulario para editar posts existentes:
app/views/posts/edit.html.erb
<% form_for(@post) do |f| %>
<%= f.error_messages %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.label :content %>
# remover esta linha que cria o textarea <%= f.text_area :content %>">
<%= fckeditor_textarea( :post, :content, :width => 600, :height => 400 ) %>
<%= f.check_box :published %>
<%= f.submit "Update" %>
<% end %>
<%= link_to 'Show', @post %> |
<%= link_to 'Back', posts_path %>
Agora, reinicie seu servidor para que ele detecte o novo plugin instalado, e crie seus blogs em formato HTML!
Extra: Para usar o FCKEditor com AJAX, basta utilizar a tag da seguinte forma:
<%= form_remote_tag :url => { :action => 'update', :id => @post }, :before => fckeditor_before_js('post', 'content') %>">
<%= fckeditor_textarea( "post", "content", :ajax => true, :width => 600, :height => 400 ) %>
<% end_form_tag %>É isso aí. Até a próxima!
quinta-feira, 2 de outubro de 2008
Act As Authenticated: Autenticacao de Usuarios
O primeiro plugin que vou exemplificar aqui eh o Act as Authenticated. Toda aplicacao web que se preze usa um sistema de autenticacao, e isso sempre envolve login, logout, usuario na sessao, propriedade do usuario sobre o conteudo, etc.
Act as Authenticated eh um otimo plugin para este fim, ja que ele quebra um galho na hora de desenvolver a parte de autenticacao de usuarios na sua aplicacao web.
Vocês vão perceber que eu vou sempre criar um projeto novo para cada plugin, pra demonstrar como funciona sua instalação e utilização desde o princípio. No nosso casso, vamos imaginar um probelma comum, onde precisamos de um sistema para gerenciamento de tarefas, com autenticação de usuários.
Primeiro vamos entao criar o projeto:
rails supertasks
cd supertasks
rake db:create
(Just in case: Lembrem-se de editar o databases.yml se estiverem trabalhando com outro banco alem do padrao, sqlite)
Agora eh hora de instalar o plugin:
script/plugin install http://svn.techno-weenie.net/projects/plugins/acts_as_authenticated
Uma vez que o plugin ja esta instalado, podemos gerar o codigo de autenticacao. Para isto, vamos considerar a classe User para representar nossos usuarios, e como controller de autenticacao vamos usar o nome SessionsController. Neste caso, basta executar o script abaixo para gerar o codigo e o comportamento de autenticacao na sua aplicacao:
ruby script/generate authenticated user sessions
Onde user se refere a nossa classe e login, o controller de autenticacao.
Considerando que voce quer confirmar a autenticacao do usuario por toda sua aplicacao, e preciso incluir o pacote que contem esta funcionalidade no seu ApplicationController (application.rb):
class ApplicationController < ActionController::Base
helper :all # include all helpers, all the time
include AuthenticatedSystem
Como nosso sistema vai conter tarefas, vamos criar um scaffold para o gerenciamento das mesmas:
script/generate scaffold task title:string content:text finished:boolean
Nos ainda precisamos adicionar a relacao do usuario com a tarefa, mas para isto vamos adicionar o user_id em uma migration separada. Nao colocamos antes no scaffold para evitar ter que mudar os templates para remover os campos referentes a user_id.
script/generate migration add_user_id_to_tasks
E edite o arquivo de migracao que foi gerado, para conter o novo campo:
def self.up
add_column :tasks, :user_id, :integer, :default => 0
end
def self.down
remove_column :tasks, :user_id
end
Eh hora de modificar as classes User e Task para criar a relacao entre ambas:
app/models/user.rb:
class User < ActiveRecord::Base
has_many :tasks
# Virtual attribute for the unencrypted password
attr_accessor :password
# Resto do codigo gerado...
app/models/task.rb:
class Task < ActiveRecord::Base
belongs_to :user
end
Vamos adicionar o before_filter no nosso controller para gerenciamento de tarefas, para garantir que nosso usuario existe na sessao antes de qualquer atividade com as mesmas:
app/controllers/tasks_controller.rb
class TasksController < ApplicationController
before_filter :login_required
Act as Authenticated disponibiliza o usuario atual em qualquer lugar, na variavel current_user. Isto eh otimo pois podemos acessar o usuario atual e garantir que as tarefas apresentadss no gerenciamento pertencem realmente aquele usuario. Para isso, devemos modificar nosso controller de artigos novamente:
class TasksController < ApplicationController
before_filter :login_required
def index
#@tasks = Task.find(:all)
@tasks = current_user.tasks
# mais codigo...
def show
#@task = Task.find(params[:id])
@task = current_user.tasks.find(params[:id])
#mais codigo...
def new
#@task = Task.new
@task = current_user.tasks.new
#mais codigo...
def edit
#@task = Task.find(params[:id])
@task = current_user.tasks.find(parmas[:id])
#mais codigo...
def create
#@task = Task.new(params[:task])
@task = current_user.tasks.new(params[:task])
#mais codigo...
def update
#@task = Task.find(params[:id])
@task = current_user.tasks.find(params[:id])
#mais codigo...
def destroy
#@task = Task.find(params[:id])
@task = current_user.tasks.find(params[:id])
#mais codigo
Com o controller criado, agora precisamos de uma pagina principal. Antes de cria-la, vamos remover o arquivo index.html dentro do diretorio public:
rm public/index.html
E criar um controller principal (Main), com apenas uma action: index
script/generate controller main index
Claro, nao podemos esquecer de definir nosso root controller em config/routes.rb:
map.root :controller => “main”
Finalmente, antes de comecar a utilizar nosso sistema, vamos dar uma cara para a nossa pagina principal. Crie o arquivo index.html.erb dentro do diretorio app/views/main:
Bem Vindo,
Vamos editar o controller de Login agora, para garantir que sempre sejamos redirecionados para nossa pagina principal. Troque, em todos os lugares onde aparece o redirecionamento para o proprio controller:
redirect_back_or_default(:controller => '/sessions', :action => 'index')
para redirecionar para nosso main controller:
redirect_back_or_default(:controller => '/main', :action => 'index')
Bom, agora eh so cruzar os dedos :-), rodar os migrations e subir o server:
rake db:migrate
ruby script/server
Bom, eh isso! Espero que sirva de ajuda para muitos projetos.
Ate a proxima!
Act as Authenticated eh um otimo plugin para este fim, ja que ele quebra um galho na hora de desenvolver a parte de autenticacao de usuarios na sua aplicacao web.
Vocês vão perceber que eu vou sempre criar um projeto novo para cada plugin, pra demonstrar como funciona sua instalação e utilização desde o princípio. No nosso casso, vamos imaginar um probelma comum, onde precisamos de um sistema para gerenciamento de tarefas, com autenticação de usuários.
Primeiro vamos entao criar o projeto:
rails supertasks
cd supertasks
rake db:create
(Just in case: Lembrem-se de editar o databases.yml se estiverem trabalhando com outro banco alem do padrao, sqlite)
Agora eh hora de instalar o plugin:
script/plugin install http://svn.techno-weenie.net/projects/plugins/acts_as_authenticated
Uma vez que o plugin ja esta instalado, podemos gerar o codigo de autenticacao. Para isto, vamos considerar a classe User para representar nossos usuarios, e como controller de autenticacao vamos usar o nome SessionsController. Neste caso, basta executar o script abaixo para gerar o codigo e o comportamento de autenticacao na sua aplicacao:
ruby script/generate authenticated user sessions
Onde user se refere a nossa classe e login, o controller de autenticacao.
Considerando que voce quer confirmar a autenticacao do usuario por toda sua aplicacao, e preciso incluir o pacote que contem esta funcionalidade no seu ApplicationController (application.rb):
class ApplicationController < ActionController::Base
helper :all # include all helpers, all the time
include AuthenticatedSystem
Como nosso sistema vai conter tarefas, vamos criar um scaffold para o gerenciamento das mesmas:
script/generate scaffold task title:string content:text finished:boolean
Nos ainda precisamos adicionar a relacao do usuario com a tarefa, mas para isto vamos adicionar o user_id em uma migration separada. Nao colocamos antes no scaffold para evitar ter que mudar os templates para remover os campos referentes a user_id.
script/generate migration add_user_id_to_tasks
E edite o arquivo de migracao que foi gerado, para conter o novo campo:
def self.up
add_column :tasks, :user_id, :integer, :default => 0
end
def self.down
remove_column :tasks, :user_id
end
Eh hora de modificar as classes User e Task para criar a relacao entre ambas:
app/models/user.rb:
class User < ActiveRecord::Base
has_many :tasks
# Virtual attribute for the unencrypted password
attr_accessor :password
# Resto do codigo gerado...
app/models/task.rb:
class Task < ActiveRecord::Base
belongs_to :user
end
Vamos adicionar o before_filter no nosso controller para gerenciamento de tarefas, para garantir que nosso usuario existe na sessao antes de qualquer atividade com as mesmas:
app/controllers/tasks_controller.rb
class TasksController < ApplicationController
before_filter :login_required
Act as Authenticated disponibiliza o usuario atual em qualquer lugar, na variavel current_user. Isto eh otimo pois podemos acessar o usuario atual e garantir que as tarefas apresentadss no gerenciamento pertencem realmente aquele usuario. Para isso, devemos modificar nosso controller de artigos novamente:
class TasksController < ApplicationController
before_filter :login_required
def index
#@tasks = Task.find(:all)
@tasks = current_user.tasks
# mais codigo...
def show
#@task = Task.find(params[:id])
@task = current_user.tasks.find(params[:id])
#mais codigo...
def new
#@task = Task.new
@task = current_user.tasks.new
#mais codigo...
def edit
#@task = Task.find(params[:id])
@task = current_user.tasks.find(parmas[:id])
#mais codigo...
def create
#@task = Task.new(params[:task])
@task = current_user.tasks.new(params[:task])
#mais codigo...
def update
#@task = Task.find(params[:id])
@task = current_user.tasks.find(params[:id])
#mais codigo...
def destroy
#@task = Task.find(params[:id])
@task = current_user.tasks.find(params[:id])
#mais codigo
Com o controller criado, agora precisamos de uma pagina principal. Antes de cria-la, vamos remover o arquivo index.html dentro do diretorio public:
rm public/index.html
E criar um controller principal (Main), com apenas uma action: index
script/generate controller main index
Claro, nao podemos esquecer de definir nosso root controller em config/routes.rb:
map.root :controller => “main”
Finalmente, antes de comecar a utilizar nosso sistema, vamos dar uma cara para a nossa pagina principal. Crie o arquivo index.html.erb dentro do diretorio app/views/main:
Bem Vindo,
Vamos editar o controller de Login agora, para garantir que sempre sejamos redirecionados para nossa pagina principal. Troque, em todos os lugares onde aparece o redirecionamento para o proprio controller:
redirect_back_or_default(:controller => '/sessions', :action => 'index')
para redirecionar para nosso main controller:
redirect_back_or_default(:controller => '/main', :action => 'index')
Bom, agora eh so cruzar os dedos :-), rodar os migrations e subir o server:
rake db:migrate
ruby script/server
Bom, eh isso! Espero que sirva de ajuda para muitos projetos.
Ate a proxima!
Welcome Folks!
Hoje pretendo iniciar uma serie de artigos sobre plugins para Ruby on Rails, sua utilização e as vantagens que podem trazer. Espero que, com a ajuda de vocês, consigamos transformar este blog numa ótima referencia para plugins em rails.
É isso aí! Mãos à obra!
And May the Force Be with you!
É isso aí! Mãos à obra!
And May the Force Be with you!
Assinar:
Postagens (Atom)