topic_id
当我通过 PUT 请求更改外键(在我的情况下)时,控制器似乎不知道帖子的“位置” 。
我不完全确定为什么会发生这种情况,但是在为此挣扎了几天之后,我真的需要一些见解。这个应用程序应该更新一个名为的对象post
,除此之外,分配一个topic_id
. 该Topic
模型通过 PostsController 通过 has_many (posts) belongs_to (topic) 关系进行更新。
事实 + 对象通过控制台和浏览器创建、编辑和销毁 + 当我手动更改 topic_id 时,帖子在浏览器中可见
我怀疑我的控制器应该受到责备,但不确定。
问题
- 为什么我的重定向不起作用?
问题示例:
考虑以下路线:
localhost:3000/blog/topics/3/posts/1
. 当我将此记录更新到topic_id = 1
浏览器时,会返回以下异常:ActiveRecord::RecordNotFound in Blog::PostsController#show
找不到 id=1 的帖子 [WHERE "posts"."topic_id" = 3]
不奇怪。但是,当我真正去路线时
localhost:3000/blog/topics/1/posts/1
,对象就存在了。此外,当主题更新时,posts 对象会从索引中消失——但这完全是另一回事。我尝试通过以下方式重构我的重定向,它们都重新创建了上述相同的错误:
- 重定向到 blog_topic_post_url([@topic,@post])..
- 重定向到 blog_topic_post_url([@post])..
- 重定向到 blog_topic_post_url(@post)..
当我尝试前两个redirect_to 调用路由重定向到时http://localhost:3000/blog/topics/blog/1/3/posts/3
,表明该对象正在存储两个主题(1 和3)???
对象参数
{"utf8"=>"✓",
"_method"=>"put",
"authenticity_token"=>"TibKWeeC8dGkxR8Jb4bQprGvllUBmiQ5+HtYAPlhn1Q=",
"post"=>{"title"=>"---- maxime",
"description"=>"---- et- facere- sunt- et- illo- reprehenderit- dolor- quis- debitis- vel",
"content"=>"---\r\n- Et asperiores eaque rem maxime laboriosam. Quos dolor perferendis in labore fugit.\r\n Delectus quam vero optio cum eius perferendis sed.\r\n- Veniam eum explicabo error minima. Dolore reprehenderit cumque reiciendis. Molestiae\r\n quo est error aut quas ut aperiam quia.\r\n- Et at quo esse aut ut accusantium alias tempore. Accusamus consequuntur sunt mollitia.\r\n Quas ut voluptate quia sit quia iste corporis. Id rerum placeat voluptas sequi non.\r\n",
**"topic_id"=>"1",**
"tags_attributes"=>{"0"=>{"_destroy"=>"0",
"tag_name"=>"---- velit",
"id"=>"1"},
"1"=>{"_destroy"=>"0",
"tag_name"=>"---- ea",
"id"=>"2"},
"2"=>{"_destroy"=>"0",
"tag_name"=>"---- impedit",
"id"=>"3"}}},
"commit"=>"Update Post",
**"topic_id"=>"3",**
"id"=>"1"}
以下是我的工作步骤:
控制器
before_filter :fetch_topic, only: [:show, :edit, :update, :destroy]
before_filter :fetch_post, only: [:show, :edit, :update, :destroy]
def edit
end
def update
respond_to do |format|
if @topic.update_attributes(params[:post]) and @post.update_attributes(params[:post])
format.html {redirect_to blog_topic_post_url([@post]), success: 'Post was successfully updated.'}
else
format.html {render :edit, error: 'Post was not updated. Please try again.'}
end
end
end
# I call these on both actions with before_filter. Works on all other relevant actions.
def fetch_topic
@topic = Topic.find(params[:topic_id])
end
def fetch_post
@post = @topic.posts.find(params[:id])
end
form.html.erb
<%= form_for([:blog, @topic, @post]) do |f| %>
...
...
<div class="field">
<%= f.fields_for(:topic) do |build_topic| %>
<%= build_topic.label :topic_name, "Select a topic" %>
<%= collection_select(:post, :topic_id, Topic.all - [@post], :id, :topic_name, prompt: true) %>
<%end%>
....
<div class="actions">
<%= f.submit %>
</div>
<% end %>