我有一个用户页面,用户可以在其中输入和提交帖子。我正在使用Ajax允许用户从用户/显示页面执行此操作。当我试图让用户删除帖子时,我遇到了这个问题。当用户点击“删除”链接时,该帖子将从页面中删除。但是,当我重新加载页面时,帖子又回来了。它没有被摧毁。
我在不同的上下文中在用户/编辑页面上实现了相同的代码,并且工作正常,因为在提交表单时销毁了帖子记录。但是,在没有提交表单的情况下,我不确定如何使用它。
这是我的设置:
:user has_many :posts
:post belongs_to :user
:post belongs_to :post_type
:post_type has_many :posts
用户#显示:
这是用户提交帖子的代码。这非常有效。
<% if logged_in? && current_user == @user %>
<% form_tag(:controller => "posts", :action => "create") do %>
<div><%= text_area_tag(:message, nil, :size => "27x3") %></div>
<div><%= submit_tag("Post") %></div>
<div><%= label_tag(:post_type_id, "Update type?", :class => 'typeLabel') %></div>
<div><%= collection_select(@posts, :post_type_id, PostType.all, :id, :name) %></div>
<% end %>
<% end %>
这是显示帖子的代码,包括问题中的“删除链接”:
<% @user.posts.each do |c| %>
<div class="postS">
<div><%=h c.message %></div>
<p><%=h c.post_type.name %></p>
<p>Posted <%=h time_ago_in_words(c.created_at) %> ago</p>
<% if logged_in? && current_user == @user %>
<%= link_to_function "- Delete Post", "if(confirm('Are you sure you want to permanently delete this post?')) $(this).up('.postS').remove()" %>
<% end %>
<%end%>
def destroy
@post = Post.find(params[:id])
if @post.destroy
redirect_to :back
else
flash[:notice] = "Post failed to delete."
redirect_to :back
end
end
如果有任何其他信息有用,请告诉我。谢谢!
我尝试使用link_to_remote
,如下面的答案中所述。我同意这是正确的解决方案,但无法使其正常运行。我认为这是因为路线问题。
我将帖子设置为这样的用户资源:
map.resources :users, :member => { :enable => :put } do |users|
users.resources :posts
end
当我实现答案中提供的link_to_remote
代码时,我得到一个“无方法错误”异常,如下所示:undefined method
post_url'for#`
我尝试了一些可以解决这个问题的调整,但我没有尝试过。有任何想法吗?我是对的,这与我的路线有关吗?
Rails指南中的代码无效。我也尝试了很多变化。
我得到的最接近的是:
<%= link_to_remote "- Delete Post", :url => { :controller => 'posts', :action => 'destroy', :id => @user.posts, :method => :delete }, :confirm => "Are you sure you want to permanetly delete this post?", :success => "$(this).up('.postS').remove();" %>
使用此代码,我单击删除链接,系统会提示我接受删除。我接受后,帖子不会在屏幕上删除。但是,它会从数据库中删除。然后,当我重新加载页面时,帖子实际上已从屏幕上删除。所以这主要是有效的,除了ajax删除操作现在不起作用。
但代码似乎错了。请注意我写了:: id =&gt; @ user.posts
这对我来说似乎不对,但这是我让这段代码完全可行的唯一方法。看看它对日志文件的作用:
处理PostsController#destroy(对于127.0.0.1 at 2009-12-17 02:07:05)[POST]
`Parameters: {"action"=>"destroy", "authenticity_token"=>"GZfPHUc2+qPa6Fj5jNogMyhuB4YUO+KlOdkwjM5NSvw=", "id"=>"12/11", "method"=>"delete", "controller"=>"posts"} `
注意id =&gt;“12/11”。这不是我想要发生的事情。
当我将id参数更改为:id =&gt; @ user.post,我得到一个“没有方法错误”。 #User:0x3ddc20c
的未定义方法`post'当我尝试:id => user_post_url(@user, @post)
时,我得到:"user_post_url
无法生成[然后它列出了此用户的所有数据库列值]。
当我尝试:id => user_posts_url(@user, @posts)
时,页面会加载。当我点击删除链接时,我被提示接受。然后什么都没发生当我重新加载页面时,帖子仍然存在,并且从未从数据库中删除。
这是我能想到的每一种变化。有什么想法吗?
这就是我的路线:
user_posts GET /users/:user_id/posts(.:format) {:controller=>"posts", :action=>"index"}
POST /users/:user_id/posts(.:format) {:controller=>"posts", :action=>"create"}
new_user_post GET /users/:user_id/posts/new(.:format) {:controller=>"posts", :action=>"new"}
edit_user_post GET /users/:user_id/posts/:id/edit(.:format) {:controller=>"posts", :action=>"edit"}
user_post GET /users/:user_id/posts/:id(.:format) {:controller=>"posts", :action=>"show"}
PUT /users/:user_id/posts/:id(.:format) {:controller=>"posts", :action=>"update"}
DELETE /users/:user_id/posts/:id(.:format) {:controller=>"posts", :action=>"destroy"}
根据以下ScottD的指导,我的代码现在看起来像这样:
<%= link_to_remote "- Delete Post", :url => user_post_url(@user,c), :method => :delete, :confirm => "Are you sure you want to permanently delete this post?", :success => "$(this).up('.postS').remove();" %>
这解决了我的大多数问题,但javascript删除操作仍然没有被触发。换句话说,我点击删除链接。帖子将从数据库中删除,但仍保留在屏幕上。当我重新加载页面时,帖子就消失了。所以,问题是以下部分没有被触发:: success =&gt; “$(本).UP( '职位')删除();”。
以下是我点击删除链接时日志中发生的情况,如上所述:
Processing PostsController#destroy (for 127.0.0.1 at 2009-12-17 11:59:18) [DELETE]
Parameters: {"action"=>"destroy", "authenticity_token"=>"ccF1QNCGs9IlvbIYWwmQmcbi7kROgQsTZjM1dM687xA=", "_method"=>"delete", "id"=>"14", "controller"=>"posts", "user_id"=>"1"}
User Columns (3.2ms) SHOW FIELDS FROM `users`
User Load (29.6ms) SELECT * FROM `users` WHERE (`users`.`id` = 1) ORDER BY name
Post Columns (8.7ms) SHOW FIELDS FROM `posts`
Post Load (1.6ms) SELECT * FROM `posts` WHERE (`posts`.`id` = 14)
app/controllers/posts_controller.rb:22:in `destroy'
SQL (0.1ms) BEGIN
app/controllers/posts_controller.rb:23:in `destroy'
Post Destroy (0.5ms) DELETE FROM `posts` WHERE `id` = 14
app/controllers/posts_controller.rb:23:in `destroy'
SQL (0.9ms) COMMIT
app/controllers/posts_controller.rb:23:in `destroy'
Redirected to http://localhost:3000/users/1
Completed in 65ms (DB: 45) | 302 Found [http://localhost/users/1/posts/14]
对我而言,这一切看起来都不错。所以我不确定为什么javascript删除不起作用。
当我重新加载页面时,日志显示正常加载的所有内容并且帖子已经消失(应该是这样)。关于如何让javascript删除工作的任何想法?
以下是基于我正在使用的link_to_remote
代码在html中生成的内容:
<a href="#" onclick="if (confirm('Are you sure you want to permanently delete this post?')) { new Ajax.Request('http://localhost:3000/users/1/posts/18', {asynchronous:true, evalScripts:true, method:'delete', onComplete:function(request){$(this).up('.postS').remove();}, parameters:'authenticity_token=' + encodeURIComponent('ccF1QNCGs9IlvbIYWwmQmcbi7kROgQsTZjM1dM687xA=')}); }; return false;">- Delete Post</a>
当我点击页面上的“删除”文字时,以下是Firebug在控制台中显示的内容:
POST http://localhost:3000/users/1/posts/18 302 Moved Temporarily
GET http://localhost:3000/users/1 200 OK
答案 0 :(得分:6)
问题是你使用link_to_function
只调用Javascript函数,它不会向你的应用发送任何内容。如果你想做Ajax,试试link_to_remote
。这将进行AJAX调用,然后它允许您基于:success
或:complete
等回调挂钩调用javascript。
基于样本的示例:
<% if logged_in? && current_user == @user %>
<%= link_to_remote "- Delete Post", :url => user_post_url(@user,c, :format => :json), :method => :delete , :confirm => "Are you sure you want to permanetly delete this post?", :success => "$(this).up('.postS').remove();" %>
<% end %>
查看Rails API docs for link_to_remote
了解更多示例。
您还需要更新Post Controller以响应Ajax的删除请求。我使用新的json gem来渲染json。
def destroy
@post = Post.find(params[:id])
respond_to do |format|
if @post.destroy
format.html { redirect_to :back }
format.json { :success => true }.as_json
else
flash[:notice] = "Post failed to delete."
format.html { redirect_to :back }
format.json { :success => false }.as_json
end
end
end
更新以反映有问题的嵌套路线。
答案 1 :(得分:0)
如果它对你有帮助我现在在我的应用程序中遇到类似的问题,直到现在我已经跟踪到了事实,除了
之外的一切:success => "$(this).up('.postS').remove();"
link_to_remote的一部分没有像想象的那样工作。由于某种原因,它没有在DOM中找到正确的div。
我并不是说这是你的问题,但它可能会让你走上正轨。