Это то, на чем я застрял некоторое время, и я должен заранее извиниться за то, что углубился в подробности такой простой проблемы. Я просто хочу прояснить, что я пытаюсь сделать здесь.
Сценарий
Итак, есть модель Foo, каждый Foo может быть красным, зеленым или синим. Наличие URL-адресов, таких как /reds
для отображения всех красных объектов и /reds/some-red-object
для отображения определенного объекта. В этом представлении «показать» должны быть следующие / предыдущие ссылки, которые по существу «находят следующий 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
Модели содержат только методы для следующего / предыдущего, которые на удивление хорошо работают.
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. Спасибо.
Обновление
Хэш параметров выглядит примерно так:
{"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>