I am using mongoid with devise invitable,
after assigning roles to user I found the following error
"**undefined method `as_document' for Array **" , any suggestions ?
invitable = find_or_initialize_with_error_by(:email, attributes[:email])
invitable.attributes = attributes
# scope_id attribute does not set properly
invitable.roles.map {|r| r.scope_id = attributes[:roles_attributes]["0"][:scope_id]}
if invitable.persisted? && !invitable.invited?
invitable.errors.add(:email, :taken)
elsif invitable.email.present? && invitable.email.match(Devise.email_regexp)
invitable.invite!
end
Whats wrong I am doing ?
This is likely because as_document doesn't work against an array, only single objects.
This is a bug with Mongoid and has_many relationships.
The method 'as_document' has to be defined for has_many relationships, like it is defined for embeds_many relationships.
I am going to make a pull request to have this issue fixed, in the meantime you can define mongoid in your gemfile like so:
gem 'mongoid', :git => https://github.com/mrjlynch.git
That happened to me with MongoId 5.1.0 when, in one direction I had "embeds_many", and in the other direction I had "belongs_to".
From what I know, the reverse of embeds_many shall be embedded_in.
Changing the reverse relationship to embedded_in fixed that issue for me.
I have to admit, this is a very obscure error message.
Related
I am facing the following issue. My game object has two associated players, as we can see:
=> game.players.count
2
However, the pluck method is returning duplicated values:
=> game.players.pluck :name
["Alice", "Alice", "Bob", "Bob"]
Both Game and Player extend ActiveRecord::Base. I have absolutely no idea of what is really going on here.
Relevant gems:
rails 4.2.8
mysql2 0.3.21
Any clue about what could be going on? Thanks in advance.
I finally found out that the Player model has a default_scope that includes the translations from globalize3 gem:
default_scope { includes(:translations) }
I removed the default scope and it started working as expected.
Hi I am using symmetric encryption (This one) gem to encrypt some fields. I have generated all the keys and followed all the steps given in it. But When I am trying to save data on my server it throws error on these lines
attr_encrypted :latitude
attr_encrypted :longitude
Error is
undefined method `encrypted_latitude' for #<Location:0x007f574a4eef50>
I have checked types, steps for gem and all looks fine.
Any idea what I am missing ...all works when I removed these lines from model. In Addition I have added attr_accessible for both fields and protected_attributes gem to make attr_accessible work
Any idea where I went wrong..Thanks
Looks like you may not have got a single instance of location. Do you have first at the end of the query?
i.e.
lat = Latitude.where( query ).first
The error means that the column named encrypted_latitude is not available in your locations table.
From the doc:
class User < ActiveRecord::Base
# Requires table users to have a column called encrypted_bank_account_number
attr_encrypted :bank_account_number
Has anyone successfully used the Rails acts_as_tenant gem for multitenancy, where the tenant ID column is not named xxx_id?
my model is something like
has_one :tenant, :foreign_key => "tenant_code"
acts_as_tenant :tenant
Then I get my query select * from [table] where tenant_id = xxx ignoring the overridden foreign_key spec.
Is there any way to fix this? or am I doing something else obviously wrong?
Thanks!!
Just as an update to this issue for future reference:
From gem version 0.3.3 onwards it is now possible to explicitly set the foreign key.
acts_as_tenant(:account, :foreign_key => 'accountID')
Perhaps this helps someone who finds this question.
ActsAsTenant sets it's own foreign key in the gem itself as (pseudocode) #{tenant_klass}_id:
def self.fkey
"#{##tenant_klass.to_s}_id"
end
https://github.com/ErwinM/acts_as_tenant/blob/master/lib/acts_as_tenant/model_extensions.rb#L12-L14
Unfortunately, I don't believe you can set your own foreign key for anything other than activerecord model relationships (with your code, you could still theoretically call model.tenant; however, that doesn't help you).
I've been trying to get my head around ActiveRecord associations but I have hit a bit of a brick wall, and no matter how much I review the ActiveRecord documentation, I can't work out how to solve my problem.
I have two classes:
Property -> has_one :contract
Contract -> belongs_to :property
In my contract class, I have a method to create_or_update_from_xml
First I check to make sure the property in question exists.
property_unique_id = xml_node.css('property_id').text
property = Property.find_by_unique_id(property_unique_id)
next unless property
And this is where I get stuck, I have a hash of attributes for the contract, and what I want to do is something like:
if property.contract.nil?
# create a new one and populate it with attributes
else
# use the existing one and update it with attributes
I know how I would go about it if it was raw SQL, but I can't get my head around hte ActiveRecord approach.
Any hints past this road block would be hugely appreciated.
Thanks in advance.
if property.contract.nil?
property.create_contract(some_attributes)
else
property.contract.update_attributes(some_attributes)
end
Should do the trick. When you have a has_one or belongs_to association then you get build_foo and create_foo methods (which are like Foo.new and Foo.create). If the association already exists then property.contract is basically just a normal active record object.
Just another way of doing it using ruby OR-Equal trick
property.contract ||= property.build_contract
property.contract.update_attributes(some_attributes)
Update:
#KayWu is right, the above ||= trick will create the contract object in the first line, rather than just building it. An alternative would be
property.build_contract unless property.contract
property.contract.update_attributes(some_attributes)
Property.all.each do |f|
c = Contract.find_or_initialize_by(property_id: f.id)
c.update(some_attributes)
end
I don't know whether this is the best solution, but for me it more succinctly
From Rails 6.1 an onwards:
property.build_contract unless property.contract
property.contract.update(some_attributes)
I am accessing a database that I can't change and it has a column named valid defined. Anytime I try to access an attribute, I get this exception:
valid? is defined by ActiveRecord
(ActiveRecord::DangerousAttributeError)
The exception makes sense, but since I'm not able to change the database, how can I get around this error?
I tried "overriding" the attribute, but I don't know how to remove the original column. I can successfully call this valid_column method, but any time I try to access another attribute defined in the database, I get the same exception. It still seems to be trying to map the valid column.
def valid_column=(valid)
write_attribute(:valid, valid)
end
def valid_column
read_attribute(:valid)
end
I'm not sure if it matters, but here are the details of my environment:
Windows Ruby 1.8.6
Informix database on a Linux server
activerecord (2.3.4)
activerecord-informix-adapter (1.0.0.9250)
ruby-informix (0.7.1)
Thanks in advance!
Try this:
class MyTable < AR:Base
class << self
def instance_method_already_implemented?(method_name)
return true if method_name == 'valid'
super
end
end
end
It's a hack, and it might not work in rails 3, but it could fix the problem for now.
I found it on the ruby on rails mailing list
If you wanted, you could also look at datamapper, which handles these sort of things somewhat more sanely.
Use safe_attributes - https://github.com/bjones/safe_attributes . It works perfectly out of the box:
class WebsiteUser < ActiveRecord::Base
establish_connection 'cf_website'
set_table_name 'nc_users'
bad_attribute_names :hash
end
Without worrying about ActiveRecord's reserved attributes, just add a gem in your gemfile and the gem will take care of name collisions automatically.
gem 'safe_attributes'
http://goo.gl/OO2H7
For reads you might be able to use SQL's select-as statement. Not sure if the following will work, but a default scope may make this easily do-able.
class MyRecord < ActiveRecord::Base
default_scope :select=> 'valid as valid_column'
end