views:

144

answers:

1

UPDATE: Solved. Thanks BusyMark!
EDIT: This is revised based on the answer below from BushyMark. I think I made all the suggested changes correctly, but I still can't get the post_type_id to save to the database when a user submits a message.

My app has a profile page. On the profile page, the owner of the page can type an update and hit "submit." The update messages appear without the page reloading (i.e. Ajax).

It basically looks like your Twitter home page. BUT, there's also a message "type" that our users select when typing an update. The message type is a pre-populated list. I've made it a model and load it as seed data in the app.

So: there is a profile model, a post model, and a post_type model.

profile has_many :posts
post belongs_to :post_type
post_type has_many :posts
The post model also has this: attr_accessible :message, :post_type_id

Routes.rb looks like this:
map.resources :users, :has_one => :profile, :has_many => :posts
map.resources :post_types

The posts controller has this method for creating the posts:

def create
  @post = current_user.profile.posts.build(:message => params[:message], :post_type_id => params[:post_type_id])
    if @post.save
      redirect_to user_profile_path
    else
      flash[:notice] = "Message failed to save."
      redirect_to user_profile_path
  end
end

The "show" view for the profile page where this all occurs looks like this:

<% form_tag(:controller => "posts", :action => "create") do %>
  <%= label_tag(:message, "Update your people") %><br />
 <%= text_area_tag(:message, nil, :size => "27x3") %>
 <div class="updateSubmit"><%= submit_tag("Update") %></div>
 <%= label_tag(:type_id, "Optional: Update type", :class => 'typeLabel') %>
    <%= collection_select(:post, :post_type_id, PostType.all, :id, :name, {:prompt => true}) %>
  <% end %>

    <% @profile.profile.posts.each do |c| %>
   <%=h c.message %></div>
   <p><%=h c.post_type %></p>
   <p>Posted <%=h time_ago_in_words(c.created_at) %> ago</p>
    <% end %>

That's the background. Here's the problem. With my current setup, when the user submits his message, the message gets sent to the posts database table, BUT the post_id does not.

My select tag is rendering like this:
<select id="post_post_type_id" name="post[post_type_id]"><option value="">Please select</option>

This is the output I get in the log when I submit a post:
Processing PostsController#create (for IP at 2009-09-03 03:03:08) [POST]

Parameters: {"message"=>"This is another test.", "commit"=>"Update", "action"=>"create", "authenticity_token"=>"redacted", "post"=>{"post_type_id"=>"3"}, "controller"=>"posts", "user_id"=>"1"}

User Load (0.3ms) SELECT * FROM "users" WHERE ("users"."id" = 1)

Profile Load (0.7ms) SELECT * FROM "profiles" WHERE ("profiles".user_id = 1) LIMIT 1

Post Create (0.5ms) INSERT INTO "posts" ("message", "updated_at", "post_type_id", "profile_id", "created_at") VALUES('Hello', '2009-09-03 20:40:24', NULL, 1, '2009-09-03 20:40:24')

Here's the relevant parts of my schema, updated per BushyMark's comments:

  `create_table "post_types", :force => true do |t|
    t.string   "name"
    t.datetime "created_at"
    t.datetime "updated_at"
  end`

  `create_table "posts", :force => true do |t|
    t.text     "message"
    t.integer  "profile_id"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.integer  "post_type_id"
  end`
+1  A: 

Couple things going on here I see so far:

type is a reserved word in Rails. It is used for single table inheritance. If you change your column name to something like "post_type" it should help immensely in trying to solve random issues. I went through this a while back and was beating my brains out before I knew about STI.

Also, you have a type_id in your post . . . but I didn't see that your post :belongs_to :type . . . don't forget that a model with the foreign key needs this declaration to use all the ActiveRecord associations.

Hope this helps!

Another Edit: I noticed that in your insert statement, it appears you have a "type" column? This will also cause issues when using relationships. Are you using a separate 'type' model? Can you possibly post your schema if any of the above statements don't help?

In ActiveRecord, a type column is reserved and will not display properly(back to my statement about Single Table Inheritance). At this point I strongly recommend getting rid of your type and type_id columns, and giving your Post a "post_type_id" column.

Then once you create a separate post_type model that has_many :posts you will want to make sure your Post :belongs_to :post_type (because it has the foreign key). Once you do that, you will be able to call post_object.post_type and it will return the model relationship you are looking for.

BushyMark
I made all these changes, but I still can't get the post_type_id to save in the database when the user submits. I'll revise my question with the new setup.
MikeH
Ok, got it. It works!. Thanks.
MikeH