Collection_select问题

时间:2009-09-03 07:08:28

标签: ruby-on-rails models helpers controllers

更新:已解决。谢谢BusyMark!
编辑:这是根据BushyMark的答案修改的。我认为我正确地做了所有建议的更改,但是当用户提交消息时,我仍然无法将post_type_id保存到数据库。

我的应用有个人资料页面。在配置文件页面上,页面所有者可以键入更新并点击“提交”。显示更新消息时没有重新加载页面(即Ajax)。

它基本上看起来像你的Twitter主页。但是,还有一个消息“类型”,我们的用户在键入更新时选择。消息类型是预先填充的列表。我已经把它作为模型并将其作为种子数据加载到应用程序中。

所以:有一个配置文件模型,一个帖子模型和一个post_type模型。

profile has_many :posts
post belongs_to :post_type
post_type has_many :posts
帖子模型也有:attr_accessible :message, :post_type_id

Routes.rb看起来像这样:
map.resources:users,:has_one => :profile, :has_many => :posts
map.resources:post_types

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

发生这一切的个人资料页面的“show”视图如下所示:

<% 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 %>

这就是背景。这是问题所在。使用我当前的设置,当用户提交他的消息时,消息将被发送到posts数据库表,但post_id不会。

我的选择标记是这样渲染的:
    <select id="post_post_type_id" name="post[post_type_id]"><option value="">Please select</option>

当我提交帖子时,这是我在日志中得到的输出:
处理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')

这是我的架构的相关部分,根据BushyMark的评论更新:

  `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 个答案:

答案 0 :(得分:1)

到目前为止我在这里看到了一些事情:

type是Rails中的保留字。它用于单表继承。如果您将列名更改为类似“post_type”的内容,则应该极大地帮助解决随机问题。在我知道STI之前,我经历了一段时间并且在击败我的脑袋。

此外,您的帖子中有一个type_id。 。 。但我没看到你的帖子:belongs_to :type。 。 。不要忘记具有外键的模型需要此声明才能使用所有ActiveRecord关联。

希望这有帮助!

另一个编辑:我注意到在你的insert语句中,你看起来有一个“类型”列?这也会在使用关系时引起问题。您使用的是单独的“类型”模型吗?如果以上任何陈述没有帮助,您是否可以发布您的架构?

在ActiveRecord中,类型列是保留的,不能正确显示(返回到我关于单表继承的语句)。此时,我强烈建议您删除type和type_id列,并为Post添加“post_type_id”列。

然后,当您创建一个单独的post_type模型has_many :posts时,您需要确保Post :belongs_to :post_type(因为它有外键)。完成后,您将能够调用post_object.post_type,它将返回您要查找的模型关系。