Note that there are some explanatory texts on larger screens.

plurals
  1. POModel types and sorting in Rails?
    text
    copied!<p>This is something I've been stuck on for a while now, and I have to apologize in advance for going into so much detail for such a simple problem. I just want to make it clear what I'm trying to do here.</p> <h2>Scenario</h2> <p>So, there's a model Foo, each Foo can either be red, green, or blue. Having URLs like <code>/reds</code> to list all red objects, and <code>/reds/some-red-object</code> to show a certain object. In that "show" view, there should be next/previous links, that would essentially "find the next RedFoo in alphabetical order, and once at the last RedFoo, the next record should be the first GreenFoo, continuing in alphabetical order, and so on".</p> <p>I've tried implementing this in a couple of ways and mostly ended up at a roadblock somewhere. I did get it working for the most part with single table inheritance though, having something like this:</p> <pre><code>class Foo &lt; ActiveRecord::Base class RedFoo &lt; Foo class GreenFoo &lt; Foo class BlueFoo &lt; Foo </code></pre> <p>Each subclass's models and controllers are identical, just replace the model names. So the controllers look something like:</p> <pre><code>class RedFoosController &lt; ApplicationController def index @foos = RedFoo.find(:all, :order =&gt; "title ASC") respond_to do |format| format.html { render :template =&gt; 'foos/index'} format.xml { render :xml =&gt; @foos } end end def show @foo = RedFoo.find(params[:id]) respond_to do |format| format.html { render :template =&gt; 'foos/show'} format.xml { render :xml =&gt; @foo } end end def new @foo = RedFoo.new respond_to do |format| format.html { render :template =&gt; 'foos/new'} format.xml { render :xml =&gt; @foo } end end def edit @foo = RedFoo.find(params[:id]) respond_to do |format| format.html { render :template =&gt; '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 =&gt; @foo, :status =&gt; :created, :location =&gt; @foo } else format.html { render :action =&gt; "new" } format.xml { render :xml =&gt; @foo.errors, :status =&gt; :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 =&gt; "edit" } format.xml { render :xml =&gt; @foo.errors, :status =&gt; :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 </code></pre> <p>The models only contain methods for next/previous, which work fine, surprisingly.</p> <pre><code>class RedFoo &lt; Foo def next if self == RedFoo.find(:all, :order =&gt; "title ASC").last GreenFoo.find(:all, :order =&gt; "title ASC").first else RedFoo.find(:first, :conditions =&gt; ["title &gt; ?", self.title], :order =&gt; "title ASC") end end def previous if self == RedFoo.find(:all, :order =&gt; "title ASC").first BlueFoo.find(:all, :order =&gt; "title ASC").last else RedFoo.find(:first, :conditions =&gt; ["title &lt; ?", self.title], :order =&gt; "title DESC") end end end </code></pre> <h2>Problem</h2> <p>For whatever reason when I try to create and edit records, none of the attributes get saved in the database. It simply adds a new record with completely empty columns, regardless of what's filled in the form. No errors get returned in the script/server output or in the log files. From the script/console however, everything works perfectly fine. I can create new records and update their attributes no problem.</p> <p>It's also quite a bad code smell that I have a lot of code duplication in my controllers/models (they're using the same views as the base model, so that's fine though). But I think that's unavoidable here unless I use some meta-goodness.</p> <p>Any advice or suggestions about tackling this record saving issue would be great, but the reason I posted my setup in detail is because I have a feeling I'm probably going about this whole thing the wrong way. So, I'm open to other approaches if you know of something more practical than using STI. Thanks.</p> <h3>Update</h3> <p>The parameters hash looks about right:</p> <pre><code>{"commit"=&gt;"Create", "authenticity_token"=&gt;"+aOA6bBSrZP2B6jsDMnKTU+DIAIkhc8fqoSicVxRJls=", "red_foo"=&gt;{"title"=&gt;"Hello world!"}} </code></pre> <p>But @foo.inspect returns the following RedFoo object (all nil, except for type):</p> <pre><code>#&lt;RedFoo id: nil, title: nil, type: "RedFoo", created_at: nil, updated_at: nil&gt; </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload