Типы моделей и сортировка в Rails? - PullRequest
4 голосов
/ 31 мая 2009

Это то, на чем я застрял некоторое время, и я должен заранее извиниться за то, что углубился в подробности такой простой проблемы. Я просто хочу прояснить, что я пытаюсь сделать здесь.

Сценарий

Итак, есть модель 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>

Ответы [ 4 ]

1 голос
/ 01 июня 2009

Проблема в параметрах

:red_foo

- это название параметров в представлении, тогда как вы используете

params[:foo]

в контроллере, я думаю, лучшим способом было бы использовать: foo, в представлении, используя text_field_tag, а не любые (как я предполагаю, могут быть) конструкторы форм text_field.

Вы можете избавиться от запаха контроллера, используя модуль для выполнения базовых задач, так как я предполагаю, что большинство новых / create / edit / update / destroy вещи такие же

OR

вы можете отобразить все маршруты на контроллере foo и использовать какой-либо параметр, переданный с маршрута или с помощью анализа URI, чтобы получить красный / зеленый / синий foo

1 голос
/ 31 мая 2009

Пожалуйста, ознакомьтесь с разделом "Наследование отдельных таблиц" на этой странице и сообщите нам, если это решит вашу проблему.

0 голосов
/ 01 июня 2009

Правильно, поэтому @ foo.inspect дает вам "ноль" в журнале?

То, что я имел в виду (если я не был достаточно ясен), было:

def create
@foo = RedFoo.new(params[:foo])
logger.error "******************* foo: #{@foo.inspect} **************"
respond_to do |format|  
  if @foo.save
  ...

если вы сделаете это и запишете свой журнал, вы можете легко узнать, что происходит с foo, и сравнить это с хэшем входящих параметров.

Infact, это также будет полезная информация, что такое хэш params?

0 голосов
/ 31 мая 2009

Должен признать, что в STI я использую set_table_name внутри модели.

, например

class RedFoo < AR::Base
  set_table_name "foos"
  include FooModule
  extend FooClassModule # for self methods

  def next; ...; end
end

Но в любом случае, что в этой ситуации говорит ваш регистратор, когда вы делаете @ foo.inspect перед сохранением, а также какой SQL-запрос запускается при вставке / обновлении?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...