では、ざっくり大枠を作る工程を、作った後の後追いで記述。
1. データベース
phpmyadmin経由でざっくりやったので、エクスポート機能の結果を転載。
sitesテーブルは、サイトの登録データ。URL、投票総数、コメント、登録ユーザの情報など。
countsテーブルは、集計・2重登録チェック用。現在はREMOTE_ADDRによる二重投稿制限のみに利用。のちのち集計データとして使いたい。
CREATE DATABASE `digg`; CREATE TABLE `sites` ( `id` int(11) NOT NULL auto_increment, `url` varchar(255) NOT NULL default '', `count` int(255) NOT NULL default '0', `comment` varchar(255) NOT NULL default '', `userid` int(11) NOT NULL default '0', PRIMARY KEY (`id`), KEY `url` (`url`), KEY `userid` (`userid`) ) TYPE=InnoDB; CREATE TABLE `counts` ( `siteid` int(255) NOT NULL default '0', `remote_addr` varchar(15) default NULL, `date` datetime NOT NULL default '0000-00-00 00:00:00', KEY `siteid` (`siteid`,`remote_addr`) ) TYPE=InnoDB;
2. config/database.yml
利用するDBにあわせて設定。ばっさり省略。
3. モデル生成
作ったテーブルのORマッパー用モデルを作成。(言ってることがおぼつかないな。。。)
generate model site generate model count
4. コントローラ生成
なぜかrecommendというコントローラ名にしてしまったようです、、、。
generate controller recommend
5. scaffoldでビューを。
生成したモデル・コントローラに合わせてviewやらなんやらを生成。scaffold。モデル名とコントローラ名を指定する。
generate scaffold site recommend
実際に直接ユーザがいじる(=recommendで操作する)のはsiteなので、モデルにsiteを指定。
6. サーバ起動、確認
この時点で確認。これでsiteテーブルオンリーなphpmyadmin的なもの完成。
ruby script/server
ここからが本番ですね!
7. 「Digg it!」ボタン的なaction追加
リンクを押すとカウント追加、という機能(action名:countup)を追加する。
ちょろちょろ修正追加。
REMOTE_ADDRによる、重複ボタン落下規制。
recommend_controller.rb ↓
... def countup id = params[:id] ra = @request.env['REMOTE_ADDR'] if Count.find(:first, :conditions => ["siteid = ? and remote_addr = ?",id,ra]) flash[:notice] = 'You have already digged it!' else count = Count.new count.siteid = id count.remote_addr = ra t = Time.now t.strftime("%Y-%m-%d") count.date = t.to_s count.save site = Site.find(id) site.count += 1 site.save end # リスト表示 redirect_to :action => 'list' end ...
list.rhtml ↓
... <% end %> <td><%= link_to 'Digg it!!', :action => 'countup', :id => site %></td> <td><%= link_to 'Show', :action => 'show', :id => site %></td> ...
この時点で、サイト登録・投票アプリ完成。
ユーザ認証を入れましょうか
8. Engine, Login_Engin Pluginの設定
radrailsでのplugin追加・設定。
右下ウィンドウのRails Pluginsから、EngineとLogin_Engineを追加
rakeの設定。
id:Kantaさんによるご紹介の通りに。多謝。
その後、右下ウィンドウのRake Tasksから、
engine_migrate ENGINE=login Go.
既存テーブルのレコードへ若干ゴミが。ううむ。手動削除。
あとは各種ファイル修正。
こちらはpylori*style wikiさんより。多謝。
environment.rb
module LoginEngine config :salt, "xxxx" config :email_from, "xxxx@xxx.xx.xx" config :admin_email, "xxxx@xxx.xx.xx" config :app_name, "fake Digg" end Engines.start :login
application.rb
require 'login_engine' class ApplicationController < ActionController::Base include LoginEngine helper :user model :user before_filter :login_required, :except => [:list, :countup] end
actionのうち、listとcountupのみ、無認証での実行許可。
application_helper.rb
module ApplicationHelper include LoginEngine end
development.rb
ActionMailer::Base.server_settings = { :address => "smtp.xxxxx.xx.xx", :domain => "xxxxxx.xx.xx", :port => 25 }
ここまでで、
・listとcountup以外のactionでは認証が必須
・認証をクリアーしていない場合、ログイン画面
・登録時に確認メールが飛び、メールのURLクリックで本登録
まで実装。すげーなplugin。
9. 「登録済みサイトを編集できるのはその登録者だけ」の実装
実際に、認証情報を利用する。
recommend.rb
... def update @site = Site.find(params[:id]) # 自分のものだけ直す if session[:user] == nil || @site.userid != session[:user].id flash[:notice] = 'You can\'t edit it.' redirect_to :action => 'list' elsif @site.update_attributes(params[:site]) flash[:notice] = 'Site was successfully updated.' redirect_to :action => 'show', :id => @site else render :action => 'edit' end end ...
_form.rhtml
... <%= text_field 'site', 'comment' %></p> <p><label for="site_userid">Userid</label><br /> <input type="hidden" name="site[userid]" value="<%= session[:user].id %>"> </p> <!--[eoform:site]--> ...
hiddenのら辺、もっと書きようがあるはずですね。
で、登録者しか登録できなくなりました。めでたしめでたし。