I want to update an specific attribut in my database after save data.
For example i have an column in my table which called pending and it's an boolean. i want to set this value to true when data was saved.
after_save :do_something
private
def do_something
self.update_column(:pending, true)
end
This doesn't work. Anyone here who has an solution?
You can modify your attribute directly like:
after_save { |user| user.username = user.username.downcase }
Try after_commit instead of after_save. It will operate outside of the save transaction.
Related
I am using ActiveAdmin. I need to store the User that created or updated every record.
So I added user_created_id and user_updated_id to every model.
On before_save I want to store the information about current_admin_user. The problem is that I cannot access current_admin_user in a model.
Is there a way to do that without breaking MVC?
I found this: http://rails-bestpractices.com/posts/47-fetch-current-user-in-models
But I am not sure if it is safe.
Any help?
Do it in controller (it's the reason that controller exist) before save:
def create
#my_model = MyModel.create params[:my_model]
#my_model.user_created = current_user
#my_model.save
end
The same with the update method.
I have a model named Form, which get fields as per user requirement, eg if user puts text field in the form then a attribute is created in Form model for storing string data.
Similarly I want to store date/time and datetime values. So I added
include Mongoid::MultiParameterAttributes
in the form model, because date and time values are submitted from for in multiple attributes.
But I get Mongoid::MultiParameterAttributes::Errors::MultiparameterAssignmentErrors exception in the controller create action, on the line #form = Form.new(params[:form])
def create
#form = Form.new(params[:form])
if #form.save
redirect_to(form_path(#form))
else
redirect_to :action => "new"
end
end
How do I get through this.
Please Help
Modify your Form class so it looks like the one below.
class Form
include Mongoid::Document
include Mongoid::MultiParameterAttributes
...
end
The ruby driver can only serialize Time objects. That might be your problem.
I have a little problem with paperclip saving the data passed through the form...
If I'm trying to save the record with .save() it won't save.. When I look in the server/log there are no errors or warnings for the paperclip gem :-/
# trying to save the record with save() -- not working :-/
def create
#baan_import = BaanImport.new(params[:baan_import])
if #baan_import.save
redirect_to(baan_imports_url)
else
render 'new'
end
end
Server-log: (using .save() in controller)
https://gist.github.com/1327347
I just don't get it why it's working if I'm using .create instead of .save()
# trying to save the record with Model.create() -- working!
def create
#baan_import = BaanImport.create(params[:baan_import])
redirect_to(baan_imports_url)
end
Server-log: (using .create() in controller)
https://gist.github.com/1327359
Can some one explain me why it's working with create and not with save??
Thanks,
Michael
Can you show us the BaanImport model. My first guess is you're possibly missing baan_upload in attr_accessible on your model, and as a result, Rails will not let you mass assign the file parameter for upload.
Can you also confirm (would appear as though it's properly set up) that your form has html => {:multipart => true} as an option?
Edit:
Is it possible to create a unique auto increment field that will be incremented on creates and updates in SQL using Rails (similar to an id field but incremented and re-assigned after an update)? For example:
Create Record A (Value: 1)
Create Record B (Value: 2)
Update Record A (Value: 3)
Update Record B (Value: 4)
I'm trying to setup pull synchronization and need a way to grab all records that have been created or updated since a previous synchronization.
I initially used the 'created_at' and 'updated_at' fields, but found them to be difficult to work with and somewhat inaccurate for partial synchronizations.
Edit:
I'm using Postgresql and Sqlite as my databases, so hopefully a solution exists that will work for both systems.
Edit:
To clarify, I want to pass a single integer to my server from the client (the largest 'sync' integer) and get back all the records created or updated after that record was created or updated.
Ended up adding a sequence integer field to my model and setup the following migration:
class CreateSequence < ActiveRecord::Migration
def self.up
begin
execute "CREATE SEQUENCE sequence"
rescue
end
end
def self.down
begin
execute "DROP SEQUENCE sequence"
rescue
end
end
end
Then, in my model I added:
before_save do
self.sequence = self.class.sequence
end
def self.sequence
s ||= self.connection.select_value("SELECT nextval('sequence') ") rescue nil
s ||= self.connection.select_value("SELECT strftime('%s','now')") rescue nil
return
end
Note: For Sqlite sequences are not supported so instead a selection of an 'epoch' form the database is required. However, this has the negative side effect of causing the sequence to be non-unique for rapid creation. However, in my case this was not an issue.
You could use a before_save callback, like so:
class MyModel < ActiveRecord::Base
before_save :increment
...
protected
def increment
self.revision ||= 1
self.revision += 1
end
end
You could make this more reusable by defining and using a Callback Class.
Another option it to use a Gem/plugin that does automatic versioning (and thus maintains a version field).
Whoops, didn't read too carefully.
If you want to grab the records that have been modified since the last sync you could create a boolean field for determining if the current record was synced. Set it to false by default and set it to false on any edit. That should allow you to pull only the items you need.
There is an id attribute that is provided by default and it auto increments. By default it is an integer, however if you were looking for a guid then let me know and I can point you to some good resources.
As far as pulling records since the last sync you could just grab the last id when you run the sync and use it as a starting value when you sync again.
So... the serial number is not associated with a row so much as a table, right?
class SerialNumber < AR::Base
has_many :thingies
# just has an integer serial number field
end
class Thingie < AR::Base
belongs_to :serial_number # probably want to include this in default scope
before_create :bump_serial
before_save : bump_serial
private
def bump_serial
self.serial_number ||= 0
self.serial_number += 1
end
end
This would appear to handle the cases of create, new/save, and update. But not destroy.
Try using the act_as_versioned gem.
It sets a version field for each record that you could use for synchronization. And I think that this would be a better way to synchronize across clients since you can compare the version on the server and client and synchronize those that are higher on the server.
The docs are here.
And the rubygem page is here.
This is very basic but not working. I want to add a callback (after_save) to upcase a field input.
In my model I have:
after_save :upcase_tax_label
def upcase_tax_label
self.tax1_label.upcase!
self.tax2_label.upcase!
end
So when I edit it should upcase the value and render in CAPS. but not. What's wrong? Thanks for your help
after_save is going to run the upcase methods after the model has already been saved to the database. In other words, it's just upcasing the object attributes in memory after the save has already completed. That's not what you want.
You want to instead use before_save so that the attributes are upcased before the object is written to the database:
before_save :upcase_tax_label
private
def upcase_tax_label
tax1_label.upcase!
tax2_label.upcase!
end
Bottom line is that you have to explicitly save a model for the changes to be made in the database. Until then, you're just playing with an object in memory.
before_save
will work. however, it's generally considered better style to write a custom setter in this situation. it would look something like this:
def tax1_label=(val)
write_attribute(:tax1_label, val.upcase)
end
def tax2_label=(val)
write_attribute(:tax2_label, val.upcase)
end