这是我一直坚持了一段时间的事情,我必须提前道歉,为这么简单的问题详细介绍.我只想说明我在这里要做的事情.
脚本
所以,有一个模型Foo,每个Foo可以是红色,绿色或蓝色.使用像/ reds这样的URL来列出所有红色对象,使用/ reds / some-red-object来显示某个对象.在“show”视图中,应该有下一个/上一个链接,基本上“按字母顺序查找下一个RedFoo,一旦在最后一个RedFoo,下一个记录应该是第一个GreenFoo,按字母顺序继续,等等上”.
我已经尝试过以下几种方式实现这一点,并且大多数都是在某个地方遇到障碍.我确实在大多数情况下使用单表继承工作,但有这样的事情:
class Foo < ActiveRecord::Base
class RedFoo < Foo
class GreenFoo < Foo
class BlueFoo < Foo
每个子类的模型和控制器都是相同的,只需替换模型名称即可.所以控制器看起来像:
class RedFoosController < ApplicationController
def index
@foos = RedFoo.find(:all, :order => "title ASC")
respond_to do |format|
format.html { render :template => 'foos/index'}
format.xml { render :xml => @foos }
end
end
def show
@foo = RedFoo.find(params[:id])
respond_to do |format|
format.html { render :template => 'foos/show'}
format.xml { render :xml => @foo }
end
end
def new
@foo = RedFoo.new
respond_to do |format|
format.html { render :template => 'foos/new'}
format.xml { render :xml => @foo }
end
end
def edit
@foo = RedFoo.find(params[:id])
respond_to do |format|
format.html { render :template => 'foos/edit'}
end
end
def create
@foo = RedFoo.new(params[:foo])
respond_to do |format|
if @foo.save
flash[:notice] = 'Foo was successfully created.'
format.html { redirect_to(@foo) }
format.xml { render :xml => @foo, :status => :created, :location => @foo }
else
format.html { render :action => "new" }
format.xml { render :xml => @foo.errors, :status => :unprocessable_entity }
end
end
end
def update
@foo = RedFoo.find(params[:id])
respond_to do |format|
if @foo.update_attributes(params[:foo])
flash[:notice] = 'Foo was successfully updated.'
format.html { redirect_to(@foo) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => @foo.errors, :status => :unprocessable_entity }
end
end
end
def destroy
@foo = RedFoo.find(params[:id])
@foo.destroy
respond_to do |format|
format.html { redirect_to(foos_url) }
format.xml { head :ok }
end
end
end
这些模型只包含next / previous的方法,这些方法工作正常,令人惊讶.
class RedFoo < Foo
def next
if self == RedFoo.find(:all, :order => "title ASC").last
GreenFoo.find(:all, :order => "title ASC").first
else
RedFoo.find(:first, :conditions => ["title > ?", self.title], :order => "title ASC")
end
end
def previous
if self == RedFoo.find(:all, :order => "title ASC").first
BlueFoo.find(:all, :order => "title ASC").last
else
RedFoo.find(:first, :conditions => ["title < ?", self.title], :order => "title DESC")
end
end
end
问题
无论出于何种原因,当我尝试创建和编辑记录时,没有任何属性会保存在数据库中.它只是添加一个具有完全空列的新记录,无论表单中填写了什么.脚本/服务器输出或日志文件中不返回任何错误.然而,从脚本/控制台,一切都很好.我可以创建新记录并更新其属性没问题.
这也是一个非常糟糕的代码味道,我在我的控制器/模型中有很多代码重复(他们使用与基本模型相同的视图,所以这很好).但我认为这是不可避免的,除非我使用一些元善意.
关于解决这个记录保存问题的任何建议或建议都会很棒,但我详细发布我的设置的原因是因为我有一种感觉,我可能会以错误的方式处理这一切.所以,如果你知道比使用STI更实用的东西,我会对其他方法持开放态度.谢谢.
更新
参数hash看起来是正确的:
{"commit"=>"Create", "authenticity_token"=>"+aOA6bBSrZP2B6jsDMnKTU+DIAIkhc8fqoSicVxRJls=", "red_foo"=>{"title"=>"Hello world!"}}
但是@foo.inspect返回以下RedFoo对象(除了类型之外所有都是nil):
#<RedFoo id: nil, title: nil, type: "RedFoo", created_at: nil, updated_at: nil>
最佳答案 问题是参数
:red_foo
是视图中params的名称,而您使用
params[:foo]
在控制器中,我认为最好的方法是使用:foo,在视图中使用text_field_tag而不是任何(我假设可以)表单构建器text_field.
你可以通过使用一个模块来完成控制器气味来做基本的东西,因为我假设大多数新的/创建/编辑/更新/破坏的东西是相同的
要么
您可以将所有路由映射到foo控制器并使用从路由传入的某种参数,或通过URI分析获取红色/绿色/蓝色foo