I am currently having a strange issue with an application migrated from rails 2.3.8 to rails 3 (3.0.1, 3.0.2, 3.0.3).
At random moments associations behave strangely. In some cases, an associated object will return the Relation object, instead of the corresponding model. This seems to happen mostly on polymorphic associations. For example:
class A
belongs_to :b, :polymorphic => true
end
class B
has_many :a, :as => :source
end
When invoking "a.b" this will "sometimes" return the Relation object (causing a "undefined method ... for ActiveRecord::Relation" error to raise) and some other times it will return the correct B object.
When the relation object is returned, it may sometimes be "fixed" temporarily by restarting the server, but it will eventually show up again.
Another issue i get is that when "getting" associated objects, sometimes the required filters are not automatically applied (where element id = ...). this causes the query to return the first object in the table and not the correct associated object.
This is becoming a very frustrating issue, specially since i don't seem to find anyone else with this or similar issues.
All finder methods in the application have been migrated to the new rails form, but this strange behavior remains.
The current configuration being used is:
Ubuntu 10
nginx server
passenger (3.0.2)
rails (3.0.3)
ruby 1.9.2p0 (2010-08-18 revision 29036)
After digging a bit deeper into the Active Record code, my co-worker and I found that the belongs_to_association.rb and belongs_to_polymorphic_association.rb were still using the old finder methods in the "find_target" method.
We ran a couple tests by logging the resulting objects of this method from different queries and discovered the old finders were returning the ActiveRecord::Relation at random moments (loading the same object it would sometimes return the object and other times the Relation object).
We overrode the find_target method for these 2 classes in initializer files, changing the finders used there to the new rails3 format (klass.select(...).where(...), etc). This seems to have solved the issue.
The "has_many" association files are already using the new format, so these haven't caused any issues.
We applied these "fixes" to the rails 3.0.3 and hope that they will be resolved in future releases.
Here are our initializer files in case someone else bumps into this problem:
belongs_to_polymorphic_association.rb:
#initializers/belongs_to_polymorphic_association.rb
module ActiveRecord
# = Active Record Belongs To Polymorphic Association
module Associations
class BelongsToPolymorphicAssociation < AssociationProxy #:nodoc:
private
def find_target
return nil if association_class.nil?
target =
if #reflection.options[:conditions]
association_class.select(#reflection.options[:select]).where(conditions).where(:id => #owner[#reflection.primary_key_name]).includes(#reflection.options[:include]).first
else
association_class.select(#reflection.options[:select]).where(:id => #owner[#reflection.primary_key_name]).includes(#reflection.options[:include]).first
end
set_inverse_instance(target, #owner)
target
end
end
end
end
belongs_to_association.rb:
#initializers/belongs_to_association.rb
module ActiveRecord
# = Active Record Belongs To Associations
module Associations
class BelongsToAssociation < AssociationProxy #:nodoc:
private
def find_target
key_column = (#reflection.options[:primary_key]) ? #reflection.options[:primary_key].to_sym : :id
options = #reflection.options.dup
(options.keys - [:select, :include, :readonly]).each do |key|
options.delete key
end
options[:conditions] = conditions
the_target= #reflection.klass.select(options[:select]).where(key_column => #owner[#reflection.primary_key_name]).where(options[:conditions]).includes(options[:include]).readonly(options[:readonly]).order(options[:order]).first if #owner[#reflection.primary_key_name]
set_inverse_instance(the_target, #owner)
the_target
end
end
end
end
Hope this is useful for someome
Thanks for sharing this. The problem with associations gone. But I still had this issue even with straight "find" method.
#post = Post.find(params[:id)
#post.update_attributes...
will fail with ActiveRecord::Relation error. However
#post = Post.find_by_id(params[:id])
#post.update_attributes...
will work
Seems like strange lazy loading behaviour
Related
I am working on a project with a 'database first' approach rest API backend. I am using ASP .Net Core 3.1 and Entity Framework 3.1.1.
I ran a script to scaffold the database into the models and db context class. However, some of the model building functions have tables/models without keys x.hasnokey(). I thought this would be fine but I get an error trying to hit the endpoint that states
ERROR : InvalidOperationException:
The navigation '' cannot be added because it targets the keyless entity type 'AAA'
Navigations can only target entity types with keys
This happens in a few different locations and this originally ran okay in the past. This is running on SQL Server 2012 (version 11). I am not sure how I can solve this issue, I have limited entity/sql experience and I just don't know where to begin. Here is the offending lines (inside DB Context):
modelBuilder.Entity<AAA>(entity =>
{
entity.HasNoKey();
entity.ToTable("BBB_AAA");
entity.HasOne(d => d.BBB)
.WithMany(p => p.AAA)
.HasForeignKey(d => d.CCC)
.OnDelete(DeleteBehavior.ClientSetNull)
...
}
The script I used to scaffold the models and db context was (generic version):
PM> Scaffold-DbContext "Server=.\SQLExpress;Database=SchoolDB;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models
I believe this might be that the database that was originally created about 10-15 years ago, cannot be made into an ORM so easily as I would have hoped. It could also a versioning issue, the scaffolding script I ran is incorrect, or if I just am out of my depth but I would appreciate being pointed in the right direction. Thank you!
This error usually comes because of Primary Key issue.
In my Case I was running this query and result was same problem you mentioned
var exists = await _dbDontext.Students.FindAsync(Id);
My Student table has relations with other tables and one of other tables was missing Primary Key.
So two Possible Solutions .
Solution 1 :
Make Primary Key column in your table that is mentioned in your error.
Solution 2 :
If things are complicated , just delete the table and Re Create It. It would work fine
I think you have two options,
1- Go and add key to the table.
2- check the following link
https://learn.microsoft.com/en-us/ef/core/modeling/keyless-entity-types
Thanks
I have a Plone 4 site which stopped to rename new Archetypes objects; after creation (as something like /temp/portaltype.2015-04-23.1234567890) and saving the first changes, including giving it a title, it should be renamed to something nicer (/temp/an-object-with-a-meaningful-name), but this doesn't happen anymore.
Perhaps the problem arose when I applied some changes to update Plone from 4.3.3 to 4.3.4 (to make one step at a time); but I have inherited a long versions.cfg which is solely sorted by package names and doesn't include any hints why certain versions were chosen ...
I'm able to go back two months and have a version which does the renaming, but without more knowledge about what to look for, it will be a very time-consuming process of re-applying every single change, rebuilding, starting and testing; but there have not been any changes to my schema definitions. I have a temp browser which is involved in delivering the primary edit form. but this doesn't seem to be the case for the saving action.
Sadly I don't fully understand yet the mechanisms of the base_edit action which should - as far as I understand - call Archetypes.BaseObject.processForm and implicitly ._renameAfterCreation, so I'd be grateful for some pointers how to debug this. Thank you!
Update:
I have a few triggers in my product's configure.zcml, e.g.:
<subscriber
for=".content.portaltype.PortalType
Products.Archetypes.interfaces.IObjectInitializedEvent"
handler=".events.onInitPortalType"/>
… with, in events.py:
def onInitPortalType(self, event):
"""
Called after first edit of new objects?
"""
print '/// onInitPortalType(%(self)r, %(event)r)' % locals()
setInitialOwner(self, event)
setStateToPrivate(self, event)
However, the event doesn't seem to be triggered, since I couldn't find the output in an instance fg session.
Update 2:
I noticed that zope.event had been pinned to a quite old version (3.5.2), so I'm trying to update to 4.3.4 more seriously now (following this how-to). This got me zope.event v4.0.3, but I have a version conflict now:
There is a version conflict.
We already have: zc.recipe.egg 1.3.2.
While:
Installing.
Getting section test.
Initializing section test.
Installing recipe zc.recipe.testrunner.
There seems to be a requirement for zc.recipe.egg < 2dev somewhere, but I can't find it.
Nothing significant changed between Plone 4.3.3 and 4.3.4 on Archetypes. Products.Archetypes changed from 1.9.7 to 1.9.8 and Products.ATContentTypes remains on the same version.
Pointers could be:
There's a _at_rename_after_creation flag, which is True by default. This can be changed on the content type class.
Is your type still activated in portal_factorytool? (Afaik this should have no impact on renaming after creation - but who knows :-))
Any Products.Archetypes.interfaces.IObjectInitializedEvent subscriber?
Issue I had once was, that the tmp id portaltype.2015-04-23.1234567890 had the wrong format and AT did no recognise it as tmp id and therefore it did not rename it after creation. The method AT uses to check if the id is autogenerated --> https://github.com/plone/Products.CMFPlone/blob/4.3.4/Products/CMFPlone/utils.py#L111 AFAIK the problem was, that the meta_type and portal_type was not the same anymore.
I'm trying to move object (i.e. image file) from one folder to another one and then rename it - overwrite with existing object (i.e. updating file).
I'm doing it in Zope (I use Plone 4.2) in the following way:
from zope.component.hooks import getSite
from zope.traversing.api import traverse
site = getSite()
src = traverse(site, "preview/")
dst = traverse(site, "images/")
source = src.manage_cutObjects(ids=[previewName])
dst.manage_pasteObjects(source)
dst.manage_delObjects(ids=[existingName])
That piece of code does what it should do, it moves the object from one folder to another, then, as manage_renameObject procedure doesn't allow overwritting I delete the existing object which will be replaced. But if I add this line of code to achieve the final goal:
dst.manage_renameObject(previewName, existingName)
the exception is thrown, that ID provided by existingName is invalid (because the object with such ID already exists and no matter that I have deleted it before).
It looks like I need some commit or update to finalize object moving (or wait etc) but I can't find anything about that.
UPDATE
I forget to add: all changes (object moving, object deletion) before exception in manage_renameObject was thrown weren't applied. Now, with transaction.commit() (as proposed by lewicki) the changes are applied but exception still occurs. Procedure transaction.savepoint() didn't help much, the exception was still thrown and changes weren't applied.
RESOLVED
I was confused initially by the error message:
<CENTER>
('Empty or invalid id specified', u'27')
</CENTER>
When I tried to reproduce the issue in the ZMI I got:
<CENTER>
The id "27" is invalid - it is already in use.
</CENTER>
and I realized that I needed to look into the code.
I dig into the installed Plone code and then located what I looked for in eggs/Zope2-2.13.18-py2.7.egg/OFS/ObjectManager.py module, in checkValidId() procedure.. There was the root of all my problems:
if not id or not isinstance(id, str):
if isinstance(id, unicode):
id = escape(id)
raise BadRequest, ('Empty or invalid id specified', id)
so, I strict object names (IDs) to str type and it all became working...
Neither commit() nor savepoint() even was needed (but initially when I was figuring out the issue and observing in ZMI that my files was neither moved nor deleted that was confused me a lot).
Thank you for your assistance!
It's dst.manage_renameObject(oldid, newid). This should work
Documentation
Yes, you're right - commit may be requred. I had a similar problem and it was solved that way:
from zope.component.hooks import getSite
from zope.traversing.api import traverse
import transaction
site = getSite()
src = traverse(site, "preview/")
dst = traverse(site, "images/")
source = src.manage_cutObjects(ids=[newName])
dst.manage_pasteObjects(source)
dst.manage_delObjects(ids=[existingName])
transaction.commit()
Now I think that
transaction.savepoint()
should be enough but you have to check on your own.
I am using the DataMapper gem with Sinatra and followed the tutorial here:
http://net.tutsplus.com/tutorials/ruby/ruby-for-newbies-working-with-datamapper/
I am connecting to the database and migrating as such:
DataMapper.setup :default, "sqlite://#{Dir.pwd}/ex2.db"
DataMapper.auto_migrate!
My data model:
class User
include DataMapper::Resource
property :id , Serial
property :username , String
property :email , String
end
I am executing using this command:
rackup config.ru
However, when I get to this line:
User.create username: "JoeSchmo", email: "joe#schmo.com"
I receive the error:
Rack::Lint::LintError: Status must be >=100 seen as integer
Any idea why this is happening?
Try deleting the SQLite DB - there seems to be a bug in data_mapper with changing the data structure and using old data. For me the bug went away after deleting the db and setting up a new one.
What version of ruby are you on because if you are on less than 1.9 you have to use the => hash constructor not : and move the colon to the beginning because it is a symbol.
User.create :username => "JoeSchmo", :email => "joe#schmo.com"
I had the same problem with Sinatra and datamapper. Creating my records with "new" keyword rather than "create" and then adding attributes one by one worked for me. Hope you find it useful.
I have a parts application that is built on Flex 3 and I having a problem with the parts list. The parts list uses two objects:
Part
ArrayOfPart
I cache the parts list locally in a SharedObject. This has been working fine for a couple months. I added a new Boolean property to the Part class and re-imported web services (which shouldn't have affected anything) and now, I can save the ArrayOfPart SharedObject fine, but when I try to retrieve the SharedObject, I get "ArgumentError: Error #1063: Argument count mismatch on ArrayOfPart. Expected 1, got 0. AND then it DELETES my SOL file completely.
(I used RegisterClass on Part and ArrayOfPart, so they both are serializable to SharedObjects)
Here's the steps I followed to get the error:
Save the shared object:
so = SharedObject.getLocal("PartsList");
so.data.AllParts = AllParts;
so.flush();
Verify the SharedObject:
The SharedObject PartsList.sol exists where it should
I opened the SharedObject file and the ArrayOfPart data looks valid
Restart the application and it retrieves the parts list from the SharedObject. This is the line that throws the Error #1063 and causes the sol file to be deleted:
so = SharedObject.getLocal("PartsList");
It looks like the data may not be well-formed when it's saved in the SharedObject? Is this possible?
I solved my own problem.
The ArrayOfPart had a constructor with a parameter. When I removed the constructor, the error went away.
By the way, this was Flash 9.
This looks like a tough one.
I don't think it is a formation or serialization issue. Maybe something else in your code is writing to the shared object?
Is there any way you can share your source? This would help as I personally don't have enough info to diagnose what is going on w/o seeing the rest of the code :(
Also....
Is there anything else that is writing to or changing this shared object?
Are all my objects created in AS3 or are some in MXML (I have noticed that the Flex compiler does not always do a good job figuring out MXML).
What version of Flash do I have?
If its Flash 10 does the same problem occur in Flash 9?
Does this happen in all browsers and on all platforms?
Just a hunch, but, since I installed Flash Player 10, I am seeing lots of errors with Shared Objects when browsing. Could it be related to newly introduced sandbox/security restrictions?