ruby-on-rails – Rails中的模型类型和排序?

这是我一直坚持了一段时间的事情,我必须提前道歉,为这么简单的问题详细介绍.我只想说明我在这里要做的事情.

脚本

所以,有一个模型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

点赞