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`