控制器PUT旧值和新值?

时间:2012-02-23 20:39:20

标签: ruby-on-rails activerecord nested-resources

当我通过PUT请求更改外键(在我的情况下为topic_id)时,控制器不会更新似乎知道帖子的位置。

我不完全确定为什么会发生这种情况,但经过几天的努力,我真的需要一些见解。该应用程序应该更新名为post的对象,并且除其他外,分配topic_idTopic模型通过PostsController通过has_many(posts)belongs_to(topic)关系更新。

事实 +通过控制台和浏览器创建,编辑和销毁对象 +当我手动更改topic_id时,帖子在浏览器中可见

我怀疑我的控制器应该受到责备,但不确定。

问题

  • 为什么我的重定向不起作用?

问题示例:

  1. 请考虑以下路线:localhost:3000/blog/topics/3/posts/1。当我将此记录更新为topic_id = 1时,浏览器将返回以下异常:

    Blog :: PostsController#show中的ActiveRecord :: RecordNotFound

    找不到帖子,其中id = 1 [WHERE“posts”。“topic_id”= 3]

  2. 不足为奇。但是,当我实际前往路线localhost:3000/blog/topics/1/posts/1时,物体就存在了。此外,当主题更新时,帖子对象会从索引中消失 - 但这完全是另一回事。

  3. 我尝试过以下方式重构我的重定向,并且它们都重新创建了上面相同的错误:

    • redirect_to blog_topic_post_url([@ topic,@ post])..
    • redirect_to blog_topic_post_url([@ post])..
    • redirect_to blog_topic_post_url(@ post)..
  4. 当我尝试前两个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 %>
    

3 个答案:

答案 0 :(得分:1)

如果您观察到更新代码,则会将其重定向到使用旧主题对象发布网址。实际上它应该更新一个@post.topic。此外,您不需要更新主题对象。

def update 
  if @post.update_attributes(params[:post])
    flash[:success]  = 'Post was successfully updated.'
    redirect_to [@post.topic, @post]
  else 
    flash[:error] = 'Post was not updated. Please try again.'
    render :action => :edit 
  end
 end

另一个问题是内部视图表单,使用集合选择您不想列出当前主题因此它应该是Topic.all - @topic

答案 1 :(得分:0)

这可能是一个排序问题,fetch_post需要设置@topic,因为两者都在before_filter中。

你能发布错误吗?

答案 2 :(得分:0)

你应该做@topic.update_attributes(params[:post])吗?这似乎有问题。它应该是@topic.update_attributes(params[:post][:topic])吗?

此外,我认为您的第一次重定向失败是因为您使用的是Topic中找到的原始fetch_topic,该Post不再与redirect_to blog_topic_post_url([@post.topic, @post]) 相关联。你可能只是明确地传递了新的帖子主题:

{{1}}
相关问题