attr_encrypted gem sometimes saving null value in database - ruby-on-rails-3

I am running rails 3 version and using attr_encrypted gem version '1.2.1' . sometimes i have seen that nil entry is getting stored into column encrypted_private_key.
Below is my model
class Device < ActiveRecord::Base
attr_encrypted :private_key, :key => proc {|device| device.log }
end
Below is how i am trying to store value in column encrypted_private_key
device = Device.new
device.private_key = "XYZ"
device.save
after doing device.save if i do device.encrypted_private_key then sometimes i am getting nil value. what could be the reason for this? This issue is not coming everytime but sometime.

Related

Rails Article.find 1 raises ActiveRecord::StatementInvalid on legacy database

I'm creating a rails app over a legacy database table. Everything works fine locally, but on the server I hit this error whenever I do Article.find(1)
Could not log "sql.active_record" event. NoMethodError: undefined method `name' for nil:NilClass
ActiveRecord::StatementInvalid: PG::Error: ERROR: zero-length delimited identifier at or near """"
LINE 1: SELECT "articles".* FROM "articles" WHERE "articles"."" = $1 LIMIT 1
The legacy database has an id field, however the schema describes the id with
create_table "articles", :id => false, :force => true do |t|
t.decimal "id", :precision => 10, :scale => 0, :null => false
...
Note that Article.find_by_id(1) returns the record without any problem.
Any ideas how to fix this?
UPDATED - See below
It turns out, adding the following to the model fixes this:
class Article < ActiveRecord::Base
set_primary_key :id
...
Presumably, because rails didn't create the table, it doesn't know what field the primary key is. It seems a little odd though, an educated guess with a warning - or even a more friendly error message - would be appreciated.
UPDATE:
Rails 3.2+ the above method is deprecated. The new method is as follows:
class Article < ActiveRecord::Base
self.primary_key = :id
...
Thanks to #lboix for pointing this out!
Seems that this option has been updated guys : set_primary_key error in Rails
Hope it will help :)
Take care

Cant update integer fields in rails

Okey i just dont understand what can be wrong here
i have this app where users are approved by and admin and this was working fine until a few days ago
in my view i have a link that calls my user controller
<%= link_to 'Approve', active_user_path(user), :method => :put %>
here is my custum route for that link
match "users/:id/activate" => "users#activate", :as => "active_user"
now in my user controller i have this activate method
def activate
#user = User.find(params[:id])
puts #user.name #the correct name is displayed
puts #user.is_approved.inspect.to_i #:is_approved is 0
if #user.update_attribute(:is_approved, 1)
puts #user.is_approved.inspect # :is_approved is 1
#user.activate_user
puts #user.is_approved.inspect # :is_approved is 1
#user.save!
redirect_to "/users?is_approved=0"
else
render "/" # dosn't matter
end
end
I try to save 3 times here (update, activate_user, save!) but still the value will not be saved, the users is_approved field is still 0, how is that possible ?
here is my model method
def activate_user
self.is_approved = 1
self.save
end
btw i can update strings with this method but not integers (true and false dosnt work either)
in my model i have is_approved as both attr_accessible and attr_accessor
The solution
Well this is awkward but so it happens that in my user model i had attr_accessor :approved this resulted in that the model never went to the database to update the :approved column BUT instead it updated the local variable :approved so next time when i looked at the column then of course the :approved value had not changed
tldr?
if you have attr_accessor in your model with the same name as the column your trying to update => remove it
Never use attr_accessor on an attribute which is backed by a database column - the accessor generated by attr_accessor will mask the value stored in the database
update_attribute actually does more than just updating a single column:
Validation is skipped.
Callbacks are invoked.
updated_at/updated_on column is updated if that column is available.
Updates all the attributes that are dirty in this object.
Are there any callbacks in your User model?
Make sure the column is not being updated somewhere in a callback.

Rails 3 validate uniqueness ignores default scope on model

I'm using the permanent_records gem in my rails 3.0.10 app, to prevent hard deletes and it seems rails is ignoring my default scope in checking uniqueness
# user.rb
class User < AR::Base
default_scope where(:deleted_at => nil)
validates_uniqueness_of :email # done by devise
end
in my rails console trying to find a user by email that has been deleted results in null, but when signing up for a new account with a deleted email address results in a validation error on the email field.
This is also the case for another model in my app
# group.rb
class Group < AR::Base
default_scope where(:deleted_at => nil)
validates_uniqueness_of :class_name
end
and that is the same case as before, deleting a group then trying to find it by class name results in nil, however when I try to create a group with a known deleted class name it fails validation.
Does anyone know if I am doing something wrong or should I just write custom validators for this behavior?
Try scoping the uniqueness check with deleted_at
validates_uniqueness_of : email, :scope => :deleted_at
This can allow two records with the same email value as long as deleted_at field is different for both. As long as deleted at is populated with the correct timestamp, which I guess permanent_records gem does, this should work.

Rails 3 saving a record issue

I have been working with Rails 3.0.5 and Ruby 1.9.2 and I have noticed that a new record doesn't get saved or isn't available for use instantly.
For example
def create
#some_record = Pool.new(params[:pool])
#some_record.users.push(current_user)
if params[:commit] == "Add More"
#some_record.save
#some_record.do_something
elsif params[:commit] == "Save"
do_something_else(params)
elsif params[:commit] == 'Cancel'
redirect_to user_url(current_user)
end
redirect_to some_other_url(current_user)
end
So when I save the record and call some_record.do_something the saved object isn't available instantly. current_user.some_records doesn't contain the newly added record but current_user.some_records.all displays the newly saved record. However on the console I am able to view the newly created record with current_user.some_records.
I'm sure I am missing something fundamental to Rails 3. I have also tried the same with current_user.some_records.build(params[:some_record] and I have the same problem. Does Rails 3 save the object instantly or is there some kind of delayed write/save because the same problem does not occur with Rails 3.0.3.
Also I am not using an authentication plugin like authlogic/devise and I simply save the current_user object to the session. I am not sure what I am doing wrong. WOuld appreciate any help?
Its also a many-to-many association between some_record and users
current_user.some_records
does not contain the newly added record because you did not save the operation after assigning #some_record.users.push(current_user).
All you have to do is to add .save after the assignment and it should work.
The model structure is not clear from your question but let's assumed that current_user belongs_to some_records
To force a database read try this:
current_user.some_records(true)
By default forcereload = false, to override this you should pass true

has any one gotten acts_as_list to work on rails 3?

I installed by putting the following line in Gemfile and 'bundle install':
gem 'acts_as_list', '>= 0.1.0'
However, when I try to use it, the results are not as expected:
technician.move_to_top #works => position = 1
technician.move_to_bottom #does not work properly; also makes position = 1
technician.move_higher #does not work; returns nil
technician.move_lower #does not work; also returns nil
Does this plugin just doesn't work with rails 3 or am I missing a step?
here is the code I'm using:
class WorkQueue < ActiveRecord::Base
has_many :technicians, :order => "position"
end
class Technician < ActiveRecord::Base
belongs_to :work_queue
acts_as_list :scope => "work_queue_id" #I also tried using work_queue
end
this is the console:
wq = WorkQueue.new
technician = Technician.last
wq.technicians << technician
Don't use "acts-as-list" gem because this gem doesn't update for a long time.
Try this:
rails plugin install git://github.com/swanandp/acts_as_list.git
acts_as_list 0.2.0 is working for me in Rails 3.2.11 on Ruby 1.9.3. However, the << syntax for adding Tasks causes problems. I used list.tasks.create() instead.
Here is a sample test:
test "acts_as_list methods" do
list = ToDoList.create(description: 'To Do List 1')
task1 = list.tasks.create(description: 'Task 1')
task2 = list.tasks.create(description: 'Task 2')
task3 = list.tasks.create(description: 'Task 3')
assert_equal 3, list.tasks.count
assert_equal task1.id, list.tasks.order(:position).first.id
assert_equal task3.id, list.tasks.order(:position).last.id
# Move the 1st item to the bottom. The 2nd item should move into 1st
list.tasks.first.move_to_bottom
assert_equal 3, list.tasks.count
assert_equal task2.id, list.tasks.order(:position).first.id
assert_equal task1.id, list.tasks.order(:position).last.id
end
When creating a new task unrelated to a to_do_list, acts_as_list will assign a position scoped against to_do_list_id == nil. Later adding an existing task to a to_do_list with << does not update the task position so acts_as_list gets confused about the positions.
Check your test.log to see the SQL statements generated by acts_as_list to get a clear picture of what is happening in your particular app.
Since it appears that your technicians are assigned after the work_queue tasks are created, you may need to manually set or re-calculate the positions after calling '<<'. You might also consider moving acts_as_list to your TechnicianWorkQueue model so acts_as_list is only invoked when you create the relationship between Technician and WorkQueue.
Looks like it should work: http://www.railsplugins.org/plugins/317-acts-as-list?version_id=418