前面有篇介绍多态的
文章,是介绍在控制台下实现的多态连接。
下面作为一个实例做个更深入的demo
首先,环境win Rails 2.0.2 mysql 5 ruby 187
插件file_column
==model:
1. User:用户
2. Blog:博客
3. Avatar:用来存放图片, 在这里存放User的头像和blog的logo
关系图:
先看model里的代码:
# avatar
class Avatar < ActiveRecord::Base
belongs_to :resource, :polymorphic => true
file_column :image
validates_format_of :image,
:with=>/^.*(.jpg|.JPG|.gif|.GIF|.png|PNG)$/,
:message => "Upload image format error. Valid format :jpg, gif or png"
file_column :image, :magick => {
:versions => { "thumb" => "125x138", "medium" => "640x480>"}
}
end
belongs_to :resource, :polymorphic => true
file_column :image
validates_format_of :image,
:with=>/^.*(.jpg|.JPG|.gif|.GIF|.png|PNG)$/,
:message => "Upload image format error. Valid format :jpg, gif or png"
file_column :image, :magick => {
:versions => { "thumb" => "125x138", "medium" => "640x480>"}
}
end
#user
class User < ActiveRecord::Base
has_one :blog
has_one :avatar, :as => :resource
end
has_one :blog
has_one :avatar, :as => :resource
end
#blog
class Blog < ActiveRecord::Base
belongs_to :user
has_one :avatar, :as => :resource
end
class Blog < ActiveRecord::Base
belongs_to :user
has_one :avatar, :as => :resource
end
再看controller里面的内容,重点是强调avatars.controller:
在new和create时,对于资源的选择是关键步骤。涉及到对不同的资源进行图像的上传。
class AvatarsController < ApplicationController
before_filter :user_or_blog
# GET /avatars/new
def new
if @resource.avatar.nil?
@avatar = @resource.build_avatar
else
render :text=>"You already have a avatar"
end
end
# GET /avatars/1;edit
def edit
@avatar = @resource.avatar
end
# avatar /avatars
# avatar /avatars.xml
def create
@avatar = @resource.build_avatar(params[:avatar])
respond_to do |format|
if @avatar.save
flash[:notice] = 'avatar was successfully created.'
format.html { redirect_to blog_avatar_url(@avatar) }
format.xml { head :created, :location => avatar_url(@avatar) }
else
format.html { render :action => "new" }
format.xml { render :xml => @avatar.errors.to_xml }
end
end
end
# PUT /avatars/1
# PUT /avatars/1.xml
def update
@avatar = @resource.avatar
respond_to do |format|
if @avatar.update_attributes(params[:avatar])
flash[:notice] = 'avatar was successfully updated.'
format.html { redirect_to avatar_url(@avatar) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => @avatar.errors.to_xml }
end
end
end
protected
def user_or_blog
if params[:user_id]
@resource=User.find(params[:user_id])
elsif params[:blog_id]
@resource= Blog.find(params[:blog_id])
end
end
end
before_filter :user_or_blog
# GET /avatars/new
def new
if @resource.avatar.nil?
@avatar = @resource.build_avatar
else
render :text=>"You already have a avatar"
end
end
# GET /avatars/1;edit
def edit
@avatar = @resource.avatar
end
# avatar /avatars
# avatar /avatars.xml
def create
@avatar = @resource.build_avatar(params[:avatar])
respond_to do |format|
if @avatar.save
flash[:notice] = 'avatar was successfully created.'
format.html { redirect_to blog_avatar_url(@avatar) }
format.xml { head :created, :location => avatar_url(@avatar) }
else
format.html { render :action => "new" }
format.xml { render :xml => @avatar.errors.to_xml }
end
end
end
# PUT /avatars/1
# PUT /avatars/1.xml
def update
@avatar = @resource.avatar
respond_to do |format|
if @avatar.update_attributes(params[:avatar])
flash[:notice] = 'avatar was successfully updated.'
format.html { redirect_to avatar_url(@avatar) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => @avatar.errors.to_xml }
end
end
end
protected
def user_or_blog
if params[:user_id]
@resource=User.find(params[:user_id])
elsif params[:blog_id]
@resource= Blog.find(params[:blog_id])
end
end
end
在new的时候,因为提交form要进行user或者blog的选择先,所以在avatars_helper.rb中写一个选择路由的方法:
module AvatarsHelper
def resource_avatar_path
if params[:user_id]
user_avatar_path
elsif params[:blog_id]
blog_avatar_path
end
end
end
def resource_avatar_path
if params[:user_id]
user_avatar_path
elsif params[:blog_id]
blog_avatar_path
end
end
end
这样在new或者是edit中提交form时就可以用resource_avatar_path进行路由了。
---在rails 2.2.2中,对于路由的nested resources设置:
map.resources :blogs, has_one=>:avatar
map.resources :users, :has_one=>:avatar
map.resources :users, :has_one=>:avatar
本文转自 fsjoy1983 51CTO博客,原文链接:http://blog.51cto.com/fsjoy/123944,如需转载请自行联系原作者