wyc
wyc

Reputation: 55283

undefined method `merge' for nil:NilClass in a form using text_field_tag

I'm following this tutorial to create tags for a model (in my case the model Post):

controllers/posts_controller.rb:

  def create
    @user = current_user
    @post = @user.posts.new(params[:post])

    if @post.save
      redirect_to @post, notice: 'post was successfully created.'
    else
      render action: "new"
    end

    @post.tag!(params[:tags])
  end

views/posts/_form.html.erb:

<%= form_for(@post) do |f| %>
  <%= render 'shared/error_messages' %>
  <div class="field">
    <%= f.label :title %><br />
    <%= f.text_field :title %>
  </div>
  <div class="field">
    <%= f.label :content %><br />
    <%= f.text_area :content %>
  </div>
  <div class="field">
    <%= f.label :tags %>
    <%= f.text_field :tags, params[:tags] %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>

views/posts/show.hmtl.erb:

<div class="tags">
  <h4>Tags:</h4>
  <%= render @post.tags %>
</div>

models/post.rb:

class Post < ActiveRecord::Base
  has_and_belongs_to_many :tags

  def tag!(tags)
    tags = tags.split(" ").map do |tag|
      Tag.find_or_create_by_name(tag)
    end
    self.tags << tags
  end
end

models/tag.rb:

class Tag < ActiveRecord::Base
  has_and_belongs_to_many :posts
end

db/migrate/(etc...)_create_tags.rb:

class CreateTags < ActiveRecord::Migration
  def change
    create_table :tags do |t|
      t.string :name
    end

    create_table :tags_posts, :id => false do | t |
      t.integer :tag_id, :post_id
    end
  end
end

Now, when I visit the posts form I get this error:

undefined method `merge' for nil:NilClass
Extracted source (around line #13):

10:   </div>
11:   <div class="field">
12:     <%= f.label :tags %>
13:     <%= f.text_field :tags, params[:tags] %>
14:   </div>
15:   <div class="actions">
16:     <%= f.submit %>

When I visit a post I get this error:

SQLite3::SQLException: no such table: posts_tags: SELECT "tags".* FROM "tags" INNER JOIN "posts_tags" ON "tags"."id" = "posts_tags"."tag_id" WHERE "posts_tags"."post_id" = 7
Extracted source (around line #24):

21: 
22:     <div class="tags">
23:       <h4>Tags:</h4>
24:       <%= render @post.tags %>
25:     </div>
26: 
27:   </div>

But I do have these tables as you can see in my schema.rb file:

 create_table "tags", :force => true do |t|
    t.string "name"
  end

  create_table "tags_posts", :id => false, :force => true do |t|
    t.integer "tag_id"
    t.integer "post_id"
  end

Any suggestions to fix this?

Upvotes: 1

Views: 8075

Answers (4)

Ruan Nawe
Ruan Nawe

Reputation: 460

<%= form_with(
  url: order_register_path(session[:order_id]),
  method: :put
) do |form| %>
  <%= form.check_box :review_budget %>
  <%= form.check_box :fast_delivery %>
  <%= form.check_box :replace_similar %>

  <div>
    <%= f.submit "Continuar" %>
  </div>
<% end %>

f.submit instead of that submit_tag

Upvotes: 0

Jason Freeman
Jason Freeman

Reputation: 31

Just in case anyone else comes across this old question through google: You need to use 'value:' for the default value in a simple form.

  <%= f.text_field :tags, value: params[:tags] %>

Upvotes: 3

uday
uday

Reputation: 8710

try this <%= f.text_field_tag :tags, params[:tags] %> in your partial _form.html.erb.

Upvotes: 1

dbrajkovic
dbrajkovic

Reputation: 3703

You have the table name backwards. HABTM looks for the models alphabetically. Look at the error carefully. It says posts_tags cannot be found. You create tags_posts. So change your table name to posts_tags.

Upvotes: 2

Related Questions