読者です 読者をやめる 読者になる 読者になる

Online.sgに参加してきた

Online.sg Rails SQLite

以前書いたOnline.sgに実際に参加してきたテーマは「続 Railsではてブもどきを作ろう」

第一回には参加できなかったので前回の分の作業も含めて作業の流れをまとめ
Railsでソーシャルブックマークを作ってみようか(第2回) - 坊やがゆく参考なのでほぼ同じ

開発環境

  • Ruby 1.8.6
  • Rails 1.2.6
  • SQLite3 3.6.1
  • sqlite3-ruby 1.2.3
SQLite3のインストール
  1. SQLite Download Pageよりsqlitedll-3_6_13.zipをダウンロード(dllファイル)
  2. Pathの通ったフォルダにdllファイルを入れる(C:\ruby\bin\)
  3. sqlite3-rubyをインストール
gem install sqlite3-ruby
Select which gem to install for your platform (i386-mswin32)
 1. sqlite3-ruby 1.2.4 (ruby)
 2. sqlite3-ruby 1.2.3 (x86-mingw32)
 3. sqlite3-ruby 1.2.3 (mswin32)
 4. sqlite3-ruby 1.2.3 (ruby)
 5. Skip this gem
 6. Cancel installation
> 3

第01回テーマ「Rails」

開発環境導入は前提としRailsプロジェクトを生成。使用DBをSQLite3に設定

rails -d sqlite3 bookmark

./config/environment.rbの1行目に$KCODE設定

$KCODE = 'u'

./app/controllers/application.rbにset_charsetを定義してbefore_filterで先に読み込ませるので以下を追加

before_filter :set_charset

private
def set_charset
  headers["Content-Type"] = "text/html; charset=utf-8"
end

Pageモデル作成

ruby script/generate model page

Migrationファイル(./db/migrate/001_create_pages.rb)を編集

class CreatePages < ActiveRecord::Migration
  def self.up
    create_table :pages do |t|
      t.column :uri, :string, :limit => 1024
      t.column :title, :string, :limit => 1024, :null => false 
    end
  end

  def self.down
    drop_table :pages
  end
end

acts_as_authenticatedプラグインをインストール

ruby script/plugin install http://svn.techno-weenie.net/projects/plugins/acts_as_authenticated

acts_as_authenticatedプラグインでモデルを作成

ruby script/generate authenticated user account

Bookmarkモデル作成

ruby script/generate model bookmark

Migrationファイル(./db/migrate/003_create_bookmarks.rb)を編集

class CreateBookmarks < ActiveRecord::Migration
  def self.up
    create_table :bookmarks do |t|
      t.column :user_id, :integer, :null => false
      t.column :page_id, :integer, :null => false
      t.column :comment, :string, :limit =>1024
      t.column :created_at, :datetime
    end
  end

  def self.down
    drop_table :bookmarks
  end
end

migrateでDBにデータを反映

rake db:migrate

第一回終了

第02回テーマ「続 Railsではてブもどきを作ろう」

has_many文にてリレーションを定義

./app/models/page.rb

class Page < ActiveRecord::Base
  has_many :users, :through => :bookmarks
  has_many :bookmarks, :order => "created_at desc"
end

./app/models/user.rb

class User < ActiveRecord::Base
  # Virtual attribute for the unencrypted password
  has_many :pages, :through => :bookmarks
  has_many :bookmarks, :order => "created_at desc"

./app/models/bookmark.rb

class Bookmark < ActiveRecord::Base
  belongs_to :user
  belongs_to :page
  validates_uniqueness_of :page_id, :scope => :user_id
end

./app/models/page.rbにuriをチェックするvalidateを定義

class Page < ActiveRecord::Base
  has_many :users, :through => :bookmarks
  has_many :bookmarks, :order => "created_at desc"

  private
  def validate
    begin
      parsed_uri = URI.parse(uri)
      raise unless parsed_uri.host
      raise unless %w(http https).include?(parsed_uri.scheme)
    rescue
      errors.add(:uri, "invalid URI")
    end
  end
end

./app/models/page.rbにタイトルが空の場合の動作を設定

def title
  self[:title].blank? ? self[:uri] : self[:title]
end

Controller作成

ruby script/generate controller page
ruby script/generate controller user
ruby script/generate controller bookmark

./app/controllers/page_controller.rbを編集

class PageController < ApplicationController
  include AuthenticatedSystem
  before_filter :login_required

  def show
    @myuser = current_user
    @page = Page.find_by_uri(params[:uri])
  end
end

./app/controllers/user_controller.rbを編集

class UserController < ApplicationController
  include AuthenticatedSystem
  before_filter :login_required

  def show
    @myuser = current_user
    @user = params[:id].nil? ? @myuser : User.find(params[:id])
  end
end

./app/controllers/bookmark_controller.rbを編集

class BookmarkController < ApplicationController
  include AuthenticatedSystem
  before_filter :login_required

  def add
    @myuser = current_user
    @page = Page.find_by_uri(params[:uri]) || Page.new(:uri => params[:uri])
    @page.title = params[:title]
    @bookmark = Bookmark.new
    @bookmark.user = @myuser
    @bookmark.page = @page
    @bookmark.comment = params[:comment]
    if request.post? && (@bookmark.save! rescue false)
      redirect_to :controller => "user", :action => "show", :id => @myuser
    else
      render(:action => "add")
    end
  end  
end

Viewファイルを作成・編集
./app/views/page/show.rhtmlを編集

<h1><%= link_to(h(@page.title), h(@page.uri)) %></h1>
<ul>
<% for bookmark in @page.bookmarks -%>
  <li>
    <%= bookmark.created_at.strftime("%Y年%m月%d日") %>
    <%= link_to(h(bookmark.user.login), :controller => "user", :action => "show", :id => bookmark.user) %>
    <%= h(bookmark.comment) %>
  </li>
<% end -%>
</ul>

./app/views/bookmark/add.rhtmlを編集

<h1>ブックマークの追加</h1>

<% if request.post? -%>
  <%= error_messages_for "page" %>
  <%= error_messages_for "bookmark" %>
<% end -%>

<%= form_tag %>
<dl>
  <dt>URI</dt>
  <dd><%= text_field_tag "uri", @page.uri, :size => 40 %></dd>
  <dt>タイトル</dt>
  <dd><%= text_field_tag "title", @page.title, :size => 40 %></dd>
  <dt>コメント</dt>
  <dd><%= text_field_tag "comment", @bookmark.comment, :size => 40 %></dd>
</dl>
<p><%= submit_tag %></p>
<%= end_form_tag %>

./app/views/user/show.rhtmlを編集

<h1><%= h(@user.login) %>さんのブックマーク</h1>
<ul>
  <% for bookmark in @user.bookmarks.find(:all, :include => [:page]) -%>
    <li>
    <%= bookmark.created_at.strftime("%Y年%m月%d日") %>
    <%= link_to(h(bookmark.page.title), :controller => "page", :action => "show", :uri => bookmark.page.uri) %>
    <%= h(bookmark.comment) %>
    </li>
  <% end -%>
</ul>

<h1><%= h(@user.login) %>さんのブックマーク</h1>
<ul>
  <% for bookmark in @user.bookmarks.find(:all, :include => [:page]) -%>
    <li>
    <%= bookmark.created_at.strftime("%Y年%m月%d日") %>
    <%= link_to(h(bookmark.page.title), :controller => "page", :action => "show", :uri => bookmark.page.uri) %>
    <%= h(bookmark.comment) %>
    </li>
  <% end -%>
</ul>

Webrickを起動

ruby script/server

表示を確認して完了
id:kabiyのソースをほぼコピペして動作確認をするというなんとも。SQLite3が何気に厄介

お疲れ様でした。次も是非参加予定