У меня есть страница пользователя, где пользователь может печатать и отправлять сообщения. Я использую 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%>
PostsController
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
Дайте мне знать, будет ли полезна любая другая информация. Спасибо!
Обновление 2
Я пытался использовать link_to_remote
, как объяснено в ответе ниже. Я согласен, что это правильное решение, но не могу заставить его работать. Я думаю, что это из-за проблемы маршрутов.
У меня есть сообщения, настроенные как пользовательский ресурс:
map.resources :users, :member => { :enable => :put } do |users|
users.resources :posts
end
Когда я реализую код link_to_remote
, указанный в ответе, я получаю исключение "ошибка метода" следующим образом: undefined method
post_url 'для # `
Я попробовал некоторые настройки, которые объясняли это, но ни одна из моих попыток не сработала. Есть идеи? Я прав, что это связано с моим маршрутом?
UPDATE
Код из Руководств по 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 => @ user.posts
Мне это не кажется правильным, но это единственный способ, как заставить этот код работать вообще. Посмотрите, что это делает с файлом журнала:
Обработка PostsController # destroy (для 127.0.0.1 в 2009-12-17 02:07:05) [POST]
`Parameters: {"action"=>"destroy", "authenticity_token"=>"GZfPHUc2+qPa6Fj5jNogMyhuB4YUO+KlOdkwjM5NSvw=", "id"=>"12/11", "method"=>"delete", "controller"=>"posts"} `
Обратите внимание на id => "12/11". Это не то, что я хочу, чтобы произошло.
Когда я изменяю параметр id на: id => @ user.post, я получаю сообщение «ошибка метода отсутствует». undefined метод `post 'для #User: 0x3ddc20c
Когда я пытаюсь :id => user_post_url(@user, @post)
, я получаю: "user_post_url
не удалось сгенерировать из [и затем в нем перечислены все значения столбца базы данных для этого пользователя].
Когда я пытаюсь :id => user_posts_url(@user, @posts)
, страница загружается. Когда я нажимаю на ссылку удаления, мне предлагается принять. Тогда ничего не происходит. Когда я перезагружаю страницу, сообщение все еще там и никогда не удаляется из базы данных.
Это все варианты, о которых я мог подумать. Есть идеи?
Обновление 3
Вот как выглядят мои маршруты:
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"}
ОБНОВЛЕНИЕ 4
Исходя из приведенных ниже рекомендаций 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 => "$ (this) .up ('. PostS'). Remove ();"
Вот что происходит в журнале, когда я нажимаю на ссылку удаления, как описано выше:
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 работать?
Обновление # 5
Вот что в настоящее время генерируется в html на основе кода link_to_remote
, который я использую:
<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