0

I am using single tablable inheritance(STI) to create different types of articles. But now I have problem while creating articles.(I can do it only in console).

Here are my models

Article.rb

class Article < ActiveRecord::Base
  attr_accessible :content, :title      
  validates :title, :presence => true
end

And TutorialArticle.rb

class TutorialArticle < Article
  attr_accessible :author  
  validates :author, :presence => true          
end

Here is my _form

<%= form_for(@article) do |f| %>
    <%= f.hidden_field :type %>    

    <div class="field">
    <%= f.label :title %><br />
    <%= f.text_field :title %>
  </div>
  <div class="field">
    <%= f.label :content %><br />
    <%= f.text_area :content %>
  </div>

  <%= render :partial => "edit" + f.object.type.downcase, :locals=>{:f=>f} %>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

But now I have a problem in article_controller.rb in create method

def create
    # create the desired subtype based on the hidden field :type in the form        
    @article = Object.const_get(params[:article][:type]).new(params[:article])      

    if @article.save
      flash[:notice] = "Successfully created post."
      redirect_to @article
    else
      render :action => 'new'
    end
  end

Now when I fill in the form and press Create Article button, I get the folloiwing error

undefined method '[]' for nil:NilClass

I even tried to hard code to understand what is wrong and if I try to change @article = Object.const_get(params[:article][:type]).new(params[:article])

to

 @article = TutorialArticle.new(params[:article]) 

my create method doesn't save the article. it just redirects to create new article page.

Could you please help me to solve the problem?

Ernest Friedman-Hill
  • 80,601
  • 10
  • 150
  • 186
lucy
  • 65
  • 8
  • can you add full backtrace? – Mike Szyndel Jul 05 '13 at 13:47
  • If you print the @article.errors info to the screen, it should help you see why it's not saving. But yeah, unless I'm missing something obvious, I don't see any blatant code issues. Perhaps also include the debugging output for the contents of your params (if not printing automatically, do puts(params) – GoGoCarl Jul 05 '13 at 14:10
  • @MichaelSzyndel : Processing by ArticlesController#create as HTML Parameters: {"utf8"=>"V", "authenticity_token"=>"0pegjWkYhPj1JHWCPYRzLTqe4Tw3U DEYpX3uTWoUWZE=", "tutorial_article"=>{"type"=>"TutorialArticle", "title"=>"Tuto rial1", "content"=>"my content", "author"=>"MyAuthor"}, "commit"=>"Create Tutori al article"} Completed 500 Internal Server Error in 0ms NoMethodError (undefined method `[]' for nil:NilClass): app/controllers/articles_controller.rb:58:in `create' ---Is that what you were asking? – lucy Jul 05 '13 at 14:13
  • @GoGoCarl : I did. If I use the hardcoaded version, then it shows that my title and author shouldn't be blank. But they are NOT blank. – lucy Jul 05 '13 at 14:16
  • @lucy - they are - look. You refer to `params[:article]` but really you are sending `tutorial_atricle`. Can you paste `new` action? – Mike Szyndel Jul 05 '13 at 14:18
  • @MichaelSzyndel- In my controller I have def new `@article = Object.const_get(params[:type]).new respond_to do |format| format.html # new.html.erb format.json { render json: @article } end end` ' and in new.html.erb----

    New article

    ´ <%= render 'form' %> <%= link_to 'Back', articles_path %>
    – lucy Jul 05 '13 at 14:31
  • @MichaelSzyndel--- and in def new I get the :type from index.html.erb

    <%= link_to "New Tutorial", new_article_path(:type=>:TutorialArticle) %>

    – lucy Jul 05 '13 at 14:34

1 Answers1

2

Ok, the printing of params helped. Add this to your TutorialArticle model:

def self.model_name
  return Article.model_name
end

This will make your forms pass article instead of tutorial_article, and the rest should work as expected. You'll need this override in all your other Article subclasses.

GoGoCarl
  • 2,519
  • 13
  • 16