我想開發一個簡單的網站,讓用戶添加帖子並在一個聚合流中查看它們。發佈模型和控制器體系結構
問題是我有2個「類型」,「消息」帖子和「鏈接」帖子的帖子。
所有帖子都必須有留言,帖子可以有鏈接。
如果帖子有一個鏈接,它必須是唯一的,所以你不能添加一個鏈接已經提交(由你或一些其他用戶)的帖子。
所以,在情況下,如果用戶增加所提供的鏈接網址,我需要驗證像鏈接早報:
- 這是一個鏈接?
- 這是新的鏈接(尚未在db中)?
- 這是一個有效的鏈接(如域存在,並且服務器響應是適當的(400301,...)
現在我堅持只是一個模型,所有的職位(有聯繫,並沒有他們),看起來像這樣:
#
# Table name: posts
#
# id :integer(4) not null, primary key
# message :string(255) default(""), not null
# link :string(2000)
# src_site_id :integer(4)
# link_type :integer(4) default(0)
# explicit :boolean(1) default(FALSE)
# view_times :integer(4)
# hidden_times :integer(4)
# tasted_times :integer(4)
# uid :integer(4)
# created_at :datetime
# updated_at :datetime
#
class Post < ActiveRecord::Base
default_scope :order => 'created_at desc'
attr_accessible :link, :message, :explicit
validates :message, :presence => true,
:length => { :maximum => 255 }
end
的問題,因爲我看到的是,我不能適用模型驗證鏈接(廣東話檢查獨特或格式),因爲它可以爲空,所以我申請的所有驗證在posts_controller像這個:
class PostsController < ApplicationController
def create
@post = Post.new(params[:post])
if @post.link.empty?
@post.link = nil
@post.save
else
if looks_like_link(@post.link)
if is_new_link(@post.link)
if is_valid_link (@post.link)
@post.save
else # url is not available
flash['error'] = 'link is not available'
end
else # link is already in db
flash['error'] = 'link is already added'
end
else
flash['error'] = 'doesnt look like a link'
end
end
redirect_to(root_path)
end
private
def looks_like_link(link)
link.match(/^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/ix)? true : false
end
def is_new_link(link)
Post.find_by_link(link) ? false : true
end
def is_valid_link(link)
require "net/http"
url = URI.parse(link)
req = Net::HTTP.new(url.host, url.port)
res = req.request_head(url.path)
flash[:error] = 'res code is ' + res.code
return res.code == '200' || res.code == '301' ? true : false
end
end
如何使這個方法正確?我得到了使用STI的建議,但我真的不知道如何以正確的方式做到這一點,以及如何應用驗證。如果你知道使用STI和驗證的好資源,請給我一個鏈接。