update tutorial rails generate create and ruby-on-rails model

ruby-on-rails - generate - ruby on rails tutorial



¿Tipos de modelos y clasificación en Rails? (4)

Correcto, entonces @ foo.inspect te da "nil" en el registro?

Lo que quiero decir (si no fuera lo suficientemente claro) fue:

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

Si haces eso y rastreas tu registro, puedes averiguar fácilmente qué está pasando con foo y compararlo con el hash de params entrantes.

De hecho, esa también sería una información útil, ¿qué es hash params?

Esto es algo en lo que he estado estancado desde hace un tiempo, y tengo que disculparme por adelantado por entrar en tantos detalles para un problema tan simple. Solo quiero dejar en claro lo que estoy tratando de hacer aquí.

Guión

Entonces, hay un modelo Foo, cada Foo puede ser rojo, verde o azul. Tener URL como /reds para enumerar todos los objetos rojos, y /reds/some-red-object para mostrar un determinado objeto. En esa vista de "mostrar", debería haber enlaces próximos / anteriores, que esencialmente "encontrarían el siguiente RedFoo en orden alfabético, y una vez en el último RedFoo, el siguiente registro debería ser el primer GreenFoo, continuando en orden alfabético, y así en".

Intenté implementar esto de varias maneras y, en general, terminé en una barricada en alguna parte. Lo logré trabajando en su mayor parte con herencia de mesa única, teniendo algo como esto:

class Foo < ActiveRecord::Base class RedFoo < Foo class GreenFoo < Foo class BlueFoo < Foo

Los modelos y controladores de cada subclase son idénticos, simplemente reemplace los nombres de los modelos. Entonces los controladores se ven algo así como:

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

Los modelos solo contienen métodos para siguiente / anterior, que funcionan bien, sorprendentemente.

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

Problema

Por alguna razón, cuando intento crear y editar registros, ninguno de los atributos se guarda en la base de datos. Simplemente agrega un nuevo registro con columnas completamente vacías, independientemente de lo que haya rellenado el formulario. No se devuelve ningún error en la secuencia de comandos / salida del servidor o en los archivos de registro. Sin embargo, desde el script / consola, todo funciona perfectamente bien. Puedo crear nuevos registros y actualizar sus atributos sin problema.

También es un mal olor de código que tengo mucha duplicación de código en mis controladores / modelos (están usando las mismas vistas que el modelo base, así que está bien). Pero creo que eso es inevitable aquí a menos que use algo de meta-bondad.

Cualquier consejo o sugerencia para abordar este problema de grabación de registros sería genial, pero la razón por la que publiqué mi configuración en detalle es porque tengo la sensación de que probablemente estoy haciendo todo esto de la manera equivocada. Entonces, estoy abierto a otros enfoques si conoces algo más práctico que usar STI. Gracias.

Actualizar

Los parámetros hash se ven a la derecha:

{"commit"=>"Create", "authenticity_token"=>"+aOA6bBSrZP2B6jsDMnKTU+DIAIkhc8fqoSicVxRJls=", "red_foo"=>{"title"=>"Hello world!"}}

Pero @ foo.inspect devuelve el siguiente objeto RedFoo (todo nulo, excepto el tipo):

#<RedFoo id: nil, title: nil, type: "RedFoo", created_at: nil, updated_at: nil>


Debo admitir que la forma en que voy sobre STI es usar set_table_name dentro de un modelo.

p.ej

class RedFoo < AR::Base set_table_name "foos" include FooModule extend FooClassModule # for self methods def next; ...; end end

Pero de todos modos, para esta situación, ¿qué dice tu registrador cuando haces un @ foo.inspect justo antes de guardar, y también qué es el SQL que se ejecuta en insert / update?


Por favor, eche un vistazo a la sección llamada "herencia de tabla única" en esta página y avísenos si resuelve su problema.


El problema es el params

:red_foo

es el nombre de los params en la vista, mientras que usted usa

params[:foo]

en el controlador, creo que la mejor manera sería usar: foo, en la vista usando text_field_tag ​​en lugar de cualquiera (lo que supongo que puede ser) form builders text_field.

Puedes salir del olor del controlador usando un módulo para hacer las cosas básicas, ya que supongo que la mayoría de las cosas nuevas / crear / editar / actualizar / destruir son las mismas

O

puede mapear todas las rutas a un controlador foo y usar algún tipo de parámetro, ya sea pasado desde la ruta, o mediante el análisis URI para obtener el foo rojo / verde / azul