I have run into a baffling situation in a Grails 2 2.5 application where my domain object is not being persisted to the MySQL database and yet no errors are being returned. I've worked with Grails for a number of years so I think I've avoided the more obvious pitfalls, and I've never seen this one before. Here's the code:
if (sale.save(flush:true,failOnError: true)) {
println "nettTotal = "+sale.nettTotal
map.response = "OK"
map.sale = sale
} else {
map.error = "Unable to save sale"
sale.errors.allErrors.each {
println it
}
}
When I run this, I see the message 'nettTotal = 290.36', showing that the domain object has in fact been saved as far as Grails is concerned (and I don't see any errors which I would do if it had failed). Yet when I do a select in the MySQL database, I see that the row in question remains unchanged ('nett_total' remains NULL, other columns are also unchanged).
The code runs in a controller, without any explicit transaction which might have failed to commit. I'm not sure where else to look. It has to be something simple, but I'm stuck.
(I'm not sure this is relevant, but this application has been proving curiously problematic with spurious errors over the last couple of weeks suggesting some kind of sporadic corruption. For example, previously working findBy* dynamic methods have suddenly started throwing errors, which have been cleared up by a 'deep clean' of the application, i.e., grails clean and the deletion of the project directory in .grails/2.2.5/projects. Yesterday I had a wholly mystifying JSON error from unchanged code which had previously worked, which was once again cleared up by a deep clean. I'm not sure why this is happening, but it worries me and I'd like to prevent it).
The problem turned out to be with a def beforeUpdate() in the Sale object. There's nothing I can see that's wrong with it, but once I'd commented it out, the update to the database was OK again.
So I was working on something and wound up having to dump multiple test dummy records in my database. Unfortunately i've been having a very difficult time figuring out how to get those deleted.
I then opened up my rails console ran
Players.count
..which gave me 93 players. I only have 73 'real' players. I also noticed that the players names i had given them were test!!!
And so I ran this command here
player = Players.where(name: "test!!!")
and received a list of the 20 players named 'test!!!'
I then went and ran this command
player.each(&:destroy)
at first the output looked really nice and it looked like everything had been taken care of. However, after scrolling down further to the very end to my utter dismay i ran into these outputs
(0.4ms) ROLLBACK
ActiveRecord::RecordNotDestroyed: ActiveRecord::RecordNotDestroyed
....and after looking at that, I re-ran
Players.count
and became disappointed to see that the same 93 players were still there. :(
I will admit that I am very much a junior when it comes to ruby on rails and such. So I will admit there is likely something that I am quite possibly missing with this one, but would anybody be able to take a look at it?
I'm guessing you want to delete players with the name test!!!. You'll need to run destroy_all on player, given that its a collection.
player = Players.where(name: "test!!!")
player.destroy_all
To delete one by one, it would be something like player.first.destroy or player.last.destroy
or find by its id and delete it, Players.find(1).destroy
I found the following method to be a HEAVY memory user on Ruby 1.8.7 and return absolutely no results (when there should be lots). The method also works like a charm on Ruby 1.9.2, returning all the wanted results while consuming no memory at all (or so!). I guess that's because a local variable has the same name as the containing method, but anyone have a clear answer for that?
def contact_of
contact_of = Circle.joins(:ties).where('ties.contact_id' => self.guid).map { |circle| circle.owner } || []
return contact_of.uniq!
end
By the way, I'm running Rails 3.1.1.
Thanks!
UPDATE : There's a part of the question that is erroneous. The fact that no contacts are returned when there should be is my misunderstading of 'uniq!' instead of 'uniq'. The first one does return 'nil' when no duplicates are found.
Still trying to figure out the memory problem...
Yeah, contact_of.uniq! would make a recursive call to the same function. I'm surprised it works in Ruby 1.9, actually.
Also, your DB query is terrible, because it retrieves a lot of unnecessary records and then does further select logic on the Ruby side. You probably want to start the find from Owner, not Circle.
I've got fullcalendar working with a small rails app (yeah) but it's sluggish because the find in my controller is finding ALL the records before it renders the calendar. I'm using a JSON approach. The field names I'm using are starts_at and ends_at. This (in the index method of the assignments_controller) works:
#assignments = Assignment.find(:all, :conditions => "starts_at IS NOT NULL")
But, as I said, it's pokey, and will only get worse as more records get added.
So this is clearly more of a rails question than a fullcalendar question: I can't figure out how to get fullcalendar to initially display the current week (when no parameters have been sent) and then accept parameters from next/previous buttons while, in either case, only looking up the relevant items from the database.
Oh - this is rails 2.x, NOT 3.
Thanks for any pointers.
Please ignore this question.
It turned out to be an issue with Date format inconsistencies between JavaScript (Epoch) and Ruby. At least that's what I think at the moment.
I'm still scratching my head, trying to figure out how exactly I "fixed" it, but it seems to be working.
I was aware of this project: http://github.com/bansalakhil/fullcalendar
but it took me ages to get the nuance of Time.at figured out.
I must say, Time is a tricky thing.
In real life as well as in code.
Thanks to everyone who gave my (misguided, as it turned out) question a glance.
I'm trying to update one of my objects in my rails app and the changes just don't stick. There are no errors, and stepping through with the debugger just reveals that it thinks everything is updating.
Anyway, here is the code in question...
qm = QuestionMembership.find(:first, :conditions => ["question_id = ? AND form_id = ?", q_id, form_id])
qm.position = x
qm.save
For reference sake, QuestionMembership has question_id, form_id, and position fields. All are integers, and have no db constraints.
That is basically my join table between Forms and Questions.
Stepping through the code, qm gets a valid object, the position of the object does get changed to the value of x, and save returns 'true'.
However, after the method exits, the object in the db is unchanged.
What am I missing?
You may not be finding the object that you think you are. Some experimenting in irb might be enlightening.
Also, as a general rule when changing only one attribute, it's better to write
qm.update_attribute(:position, x)
instead of setting and saving. Rails will then update only that column instead of the entire row. And you also get the benefit of the data being scrubbed.
Is there an after_save?
Is the correct SQL being emitted?
In development log, you can actually see the sql that is generated.
For something like this:
qm = QuestionMembership.find(:first, :conditions => ["question_id = ? AND form_id = ?", q_id, form_id])
qm.position = x
qm.save
You should see something to the effect of:
SELECT * FROM question_memberships WHERE question_id=2 AND form_id=6 LIMIT 1
UPDATE question_memberships SET position = x WHERE id = 5
Can you output what sql you are actually seeing so we can compare?
Either update the attribute or call:
qm.reload
after the qm.save
What is the result of qm.save? True or false? And what about qm.errors, does that provide anything that makes sense to you? And what does the development.log say?
I have run into this problem rather frequently. (I was about to say consistently, but I cannot, as that would imply that I would know when it was about to happen.)
While I have no solution to the underlying issue, I have found that it seems to happen to me only when I am trying to update mysql text fields. My workaround has been to set the field to do something like:
qm.position = ""
qm.save
qm.position = x
qm.save
And to answer everyone else... when I run qm.save! I get no errors. I have not tried qm.save?
When I run through my code in the rails console everything works perfectly as evidenced by re-finding the object using the same query brings the expected results.
I have the same issue when using qm.update_attribute(... as well
My workaround has gotten me limping this far, but hopefully someone on this thread will be able to help.
Try changing qm.save to qm.save! and see if you get an exception message.
Edit: What happens when you watch the log on the call to .save!? Does it generate the expected SQL?
Use ./script/console and run this script.. step by step..
see if the position field for the object is update or not when you run line 2
then hit qm.save or qm.save!... to test
see what happens. Also as mentioned by Tim .. check the logs
Check your QuestionMembership class and verify that position does not have something like
attr_readonly :position
Best way to debug this is to do
tail -f log/development.log
And then open another console and do the code executing the save statement. Verify that the actual SQL Update statement is executed.
Check to make sure your database settings are correct. If you're working with multiple databases (or haven't changed the default sqlite3 database to MySQL) you may be working with the wrong database.
Run the commands in ./script/console to see if you see the same behavior.
Verify that a similar object (say a Form or Question) saves.
If the Form or Question saves, find the difference between the QuestionMembership and Form or Question object.
Turns out that it was emitting the wrong SQL. Basically it was looking for the QuestionMembeship object by the id column which doesn't exist.
I was under the impression that that column was unnecessary with has_many_through relationships, although it seems I was misguided.
To fix, I simply added the id column to the table as a primary key. Thanks for all the pointers.