Thanks for your help with this! I have many newsavedmaps, and each can have multiple waypoints. The waypoints table connects to the newsavedmaps id with a field, "newsavedmap_id." I am new to Rails (using Rails 2), and I'm having trouble with a destroy feature. Essentially, if a user gets rid of a newsavedmap, I also want to eliminate the waypoints.
newsavedmap.rb
has_many :waypoints, :dependent => :destroy
waypoint.rb
belongs_to :newsavedmap
newsavedmap controller (I think this is the problem)
def destroy
#newsavedmap = Newsavedmap.find(params[:id])
#waypoint = Waypoint.find(params[:id])
#newsavedmap.destroy
#waypoint.destroy
respond_to do |format|
format.html { redirect_to "/CODE" }
format.xml { head :ok }
end
end
I also have a view, newmaps.html.erb. A user sees his newsavedmap on the page, and he can click a link:
When he does, this is the javascript that kicks in:
$('.newremovemap').click(function(){
if (confirm('Are you sure you want to remove this map?')) {
var mappage = $(this).closest('.wholemap');
var map = $(this).parent();
$.post(this.href, { _method: "delete", authenticity_token: $('#auth_token').val() }, function(){
mappage.fadeOut();
});
};
return false;
})
Now, when I click the link, the alert message repeats many times, but the records are not removed. The error code is ActiveRecord::RecordNotFound (Couldn't find Waypoint without an ID). I've tried applying links like this to the problem (
Rails dependent destroy error), but I can't seem to find a solution.
you need to just destroy the newsavedmap, and associated waypoints will be automatically deleted.
def destroy
#newsavedmap = Newsavedmap.find(params[:id])
#newsavedmap.destroy
respond_to do |format|
format.html { redirect_to "/CODE" }
format.xml { head :ok }
end
end
the other most important thing is that with a single params[:id], you are trying to find objects of two classes(Newsavedmap,Waypoint), that is wrong. as per the code link is for Newsavedmap and hence you can find its object by params[:id], not of Waypoint.
One more thing, that is important that you are trying to call a javascript function on that click, which is redirecting to newsavedmap show page.Try to change that link as well :
<%= link_to 'Destroy', newsavedmap_path(#newsavedmap),
:confirm => 'Are you sure?', :method => :delete %>
If you have added the dependent destroy in newsavedmap you don't need to call
#waypoint.destroy // not needed
Related
I'm building an Events site using RoR which I've just upgraded to v5.0.1 (not moving to 5.1 just yet). My events show page has a comments section at the foot of the page which, so far, only has a create and delete functionality.
I want to add an Edit/Update function to comments so only the user who created the comment can edit the comment if they see fit. I want them to be able to edit their comment whilst on the same page.
I'm trying to implement these changes using remote: true & Ajax, rather than rely on a gem as it doesn't appear too complex, but I've never done this before and there doesn't appear to be a clear guide via the internet/SO. Here's my views & controller code -
comments_controller.rb
def create
#event = Event.find(params[:event_id])
#comment = #event.comments.create!(params[:comment].permit(:name, :body))
#comment.user_id = current_user.id
redirect_to #event
end
def update
#comment.user = current_user
respond_to do |format|
if #comment.update
format.html { redirect_to #comment, notice: 'Comment was successfully updated.' }
format.js { }
format.json { render :show, status: :created, location: #comment }
else
format.html { render :new }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
def destroy
#event = Event.find(params[:event_id])
#comment = #event.comments.find(params[:id])
#comment.destroy
redirect_to event_path(#event)
end
_comments.html.erb
<% if user_signed_in? %>
<p><%= link_to "Edit", remote: true %></p>
<p><%= link_to 'Delete', [comment.event, comment],
method: :delete,
class: "button",
data: { confirm: 'Are you sure?' } %></p>
<% end %>
My understanding is that I need to include a .js.erb file in my views/comments folder to deal with this ( edit.js.erb ?) but what I'm not clear on is exactly what javascript code I need to include in order for this to work. Also, I don't think my controller code above seems right - should this go in the Edit action? Do I also need an Event#show action in my events controller as this is where it sits in the views?
Any assistance would be greatly appreciated.
I realize this doesn't answer your question, but hopefully it'll solve headaches down the road for you as far as reinventing the wheel goes. It's also why (I believe) you're seeing downvotes.
I don't want to use best_in_place gem as it appears to not have been updated for a while and I'm not sure if its the best fit for Rails 5.0.
Gems don't need to have activity to still be useful. By "for a while", you must mean mean "less than 24 hours ago" because I'm seeing plenty of activity over the last month. Once a Gem solves its usually good to go.
https://github.com/bernat/best_in_place/commits/master
Rails 5 still handles POST requests right? Then it should work. best_in_place is more javascript-heavy than anything. https://github.com/bernat/best_in_place/tree/master/lib/best_in_place
The most "daunting" code in there is the helper.rb file, which renders the HTML that hooks into the JS library.
Update:
The comments/edit.js.erb file would be responsible for inserting the form to edit the comment, such as $('div#new_comment').append('<%= j render 'form' %>');
This assumes you're using Rails' conventions in regards to element/ID naming.
If you have a link_to("Edit", edit_comment_path(comment), :remote => true) everything should fire automatically.
Here's an example repo using Rails 4; should be the same for Rails 5, with the exception of (maybe) respond_to blocks? I'm not sure, haven't used Rails 5 yet. Just do a bundle, rake db:setup, and then a rails s; navigate to http://localhost:3000/events and enjoy.
You're on the right track with edit.js.erb. The file should contain JS code to set up the screen for editing, which might be hiding a DIV and displaying an INPUT or TEXTAREA instead, for example.
Of course, the file can also contain Ruby code as well, inside <% %> tags.
When I go to delete a post I keep receiving an error that says
undefined method `destroy' for "Tech":String
The "tech" part of the posts varies with whatever the tag is of the post I am trying to delete. I am not sure what the problem is. I am using acts_as_taggable_on if that has anything to do with it.
This is my destroy method in my posts controller:
def destroy
#post = Post.find(params[:id])
#post.destroy
respond_to do |format|
format.html { redirect_to(root_path) }
format.xml { head :ok }
format.json { head :ok }
end
end
The delete button in my post show:
<%= button_to 'Delete', #post, :method => :delete, :confirm => "Are you sure?" %>
Tags are saved in the database as a string.
It's impossible to give you an answer to fix your problem, because you are giving no code and no examples.
Nonetheless that error means you are calling the destroy method on a string, and strings in Ruby do not have a destroy method defined.
Check where are you calling destroy, because it seems you are doing it in some function that returns a string (a tag name in your case). You must do it on an object that is an instance of the Tag class.
I have a rails 3.1 app and i cant seem to delete my images via ajax. my code smaple is
def destroy
#photo = Photo.find(params[:id])
#photo.destroy
respond_to do |format|
format.html { redirect_to(user_photos_path(current_user)) }
format.js { render :nothing => true }
end
end
then in my views i have
<%= link_to '(delete)', profile_photo_path(photo.profile, photo), :method => :delete if me %>
in my application.js i have
$('.delete_post').bind('ajax:success', function() {
$(this).closest('tr').fadeOut();
});
it does not work for me. it performs the action but it does not fade out
In your ajax:success callback this is not bound to the .delete_post link as you expect it to be. Maybe you could add IDs to your links, then in your controller or template generate some javascript like $("#photo_17_delete").closest('tr').fadeOut();. That's just an example of one way to handle it.
It's an old question but I just wanted to point out that it seems like it's a bad practice to use links to actions that modify or destroy your data.
You should be using to_button instead
http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-button_to
I'm trying to do something fairly simple but I'm not sure the rails way to do it. At its simplest, I have an index page where you can sign up for a mailing list.
I'm trying to set it up so that you can add yourself to the mailing list from the index page without ever seeing the mailing list views. I can submit the data properly using something like:
= form_for #mailing_list, :remote => true do |form|
= if #mailing_list.errors.any?
%ul
= #mailing_list.errors.full_messages.each do |message|
%li
= message
.field
= form.label :email, 'Your email'
= form.text_field :email
= form.submit "Add to Mailing List"
With the controller:
def create
#mailing_list = MailingList.new(params[:mailing_list])
if #mailing_list.save
redirect_to(:root, :notice => 'Mailing list was successfully created.')
else
? How do I return the errors ?
end
end
But I am unable to get the errors back (ie. Email not valid, etc.). Is there a better way to do what I'm attempting? I would just like to be able to call and respond to actions of the MailingList controller from the index page view...
I believe that you are wanting a form that will add someone to a Mailing list without leaving that page.
Better? Hmmm.. Well, I'll tell you what I do and you can decide what you like.
I would use respond_to in the controller to differentiate between the standard html call and the remote js call. Then, I would handle the page changes in the view. I like keeping the display in the views.
Controller:
def create
#mailing_list = MailingList.new(params[:mailing_list])
if #mailing_list.save
respond_to do |format|
format.html { redirect_to(:root, :notice => 'Mailing list was successfully created.') }
format.js { render }
end
else
respond_to do |format|
format.html { render }
format.js { render :errors }
end
end
end
create.js.erb
$('#errors').html('').hide();
$('form').html('Mailing list was successfully created.'); // needs a better element
errors.js.erb
$('#errors').html('<%= escape_javascript(#mailing_list.errors.full_messages.collect { |msg| content_tag :li, msg }.join().html_safe) %>').show();
You can do something with the errors object on #mailing_list, e.g.
flash.now[:error] = #mailing_list.errors.full_messages
Since, I am new to rails, so I have want to know a small functionality.
I have a reports model in my rails 3 application(not by scaffolding). I am displaying reports one by one through ajax functionality. I want to add a delete link to my each report. I have also created the destroy method in my controller. Now, I don't know how to delete a specific report when I click on the delete link of that particular report.
Here's my controller code:-
class ReportsController < ApplicationController
def index
#reports = Report.all(:order => "created_at DESC")
respond_to do |format|
format.html
end
end
def create
#report = Report.create(:description => params[:description])
respond_to do |format|
if #report.save
format.html { redirect_to reports_path }
format.js
else
flash[:notice] = "Report failed to save."
format.html { redirect_to reports_path }
end
end
end
def destroy
#report = Report.find(params[:id])
if #report.destroy
format.html { redirect_to reports_path }
format.js
end
end
end
You can assume that my reports are being displayed in the twitter-timeline format and I want to add the delete report feature to each report. Please help me out.
In your view you'd add a link, button, etc. to send the delete action back to the server.
Using link_to for example:
link_to("Destroy", report_path(report), :method => :delete, :confirm => "Are you sure?")
You can do the same with button_to.
Update:
Sorry I missed the AJAX mention (thanks Jeffrey W.).
You'll also want to add :remote => true if you want to send the delete via AJAX.