`foreign_type` relationship failing on Rails 6 - ruby-on-rails-6

I'm trying to understand this relationship setup on this model, and why is this an issue on Rails 6.
Coming from Rails 3, this relationship is defined as:
belongs_to :entity foreign_key: 'user_id', foreign_type: 'ruby_type'
This worked fine, all the way up to Rails 5 (At least our crawl and traceroute did not bring this as an issue).
However, once we got to Rails 6, we found the following:
ArgumentError: Unknown key: :foreign_type. Valid keys are: :class_name, :anonymous_class, :primary_key, :foreign_key, :dependent, :validate, :inverse_of, :strict_loading, :autosave, :required, :touch, :polymorphic, :counter_cache, :optional, :default
Was this syntax changed for Rails 6?

foreign_type option can only be applied together with polymorphic - so make sure this is a polymorphic association you are after. If the association is not polymorphic I would get rid of foreign_type.
belongs_to :entity, foreign_key: 'user_id', foreign_type: 'ruby_type', polymorphic: true

Related

Navigations can only target entity types with keys

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

Configuration to allow optional belongs_to association not working in rail 6

In rails 5, I could make belongs_to association optional using this setting:
Rails.application.config.active_record.belongs_to_required_by_default = false
but this does not appear to work in Rails 6. Is there a way to do this in Rail 6?
Looking at the new framework defaults file for Rails 5, it had the following
# config/initializers/new_framework_defaults.rb
# Require `belongs_to` associations by default. Previous versions had false.
Rails.application.config.active_record.belongs_to_required_by_default = true
So it appears that the option has been removed completely for Rails 6. So you will need to do it on a case by case basis by adding optional: true. In my case, in most cases, I ended rewriting the code so that the association was required.
The option still works in Rails 6, but you need to make sure you set it after loading default config values, i.e.
config.load_defaults 6.0
The best place place would be towards the end of config/application.rb
...
# Don't check for the existence of belongs_to records
config.active_record.belongs_to_required_by_default = false
end
end

aem-6-2-replication-issue-for-node-containing-invalid-jcr-names

I am working on AEM 5.6 to 6.2 upgrade project. There are some nodes in aem 5.6 environment which contains invalid character(as per JCR naming convention like rte[2] is one of the node name which doesn't follow the naming convention)but somehow we are able to replicate those nodes in 5.6 environment. After upgrade it to aem 6.2,it seems like JCR is more restricted and won't allow the nodes to replicate if it is having invalid characters.
Getting the below error in aem 6.2: error:
com.day.cq.replication.ReplicationException: Repository error during node import: Cannot create a new node using a name including an index
Is there any way we can configure AEM 6.2 to stop checking JCR node names?or any other solution?
JCR 2 does not allow [ as a valid character therefore you won't get an easy workaround for this. It's one of the limitations just like the same-named-sibling.
My recommendation will be to modify these nodes before the upgrade/migration to 6.2. This can be complicated and costly for business but 6.2 won't allow it.
As a background [ was allowed in older version due to twisted support for grammar syntax for same-named-siblings.
Assuming that these are all content nodes as nothing out-of-the-box in AEM 5.x follows this naming convention.
Some ways to fix it:
Write a custom servlet to query and rename the paths across all references. You will have to test your content for these renames.
Use Groovy console (https://github.com/OlsonDigital/aem-groovy-console) to rename the nodes.
In either case, you will need to modify the nodes before the migration as the structure is not oak compliant therefore you cannot use crx2oak commit hooks also. This can be done with both in-place upgrade and side-by-side migration. This is similar to the problem with same named siblings that must be corrected before the migration.
Some efficiency techniques that might help:
Write queries to find invalid node names on top-level nodes like /content/mysite-a, /content/mysite-b etc. Don't run root level queries on /content as it might downgrade to
traversal and halt the execution.
Ensure that all references are updated in same commit. If you are using custom servlet, call session.save() only after updating all the node names and it's corresponding references.
As i mention in the comment this replication failure causes because of the oak workspace restriction as the code snippet below
//handle index
if (oakName.contains("["))
{ throw new RepositoryException("Cannot create a new node using a name including an index");
}
and i feel you can't escape this constraint as it it required by the repository to maintain consistency
you can find nodes that ends with '[', by below query
SELECT [jcr:path] FROM [nt:base] WHERE ISDESCENDANTNODE('/content/path/') AND [jcr:path] like '%\['
and to modify the JCR/CRX nodes you can use CURL or SlingPostServlet method
Some helpful posts are blow.
https://github.com/paulrohrbeck/aem-links/blob/master/curl_cheatsheet.md
http://sling.apache.org/site/manipulating-content-the-slingpostservlet-servletspost.html
Can you try migrating using a tool like oak-upgrade and let us know if you are still facing this issue.
The tool is robust and you have the flexibility to configure specific sub-trees for migration using this tool.

symfony2 console arguments

I want to create a single named argument/option for symfony command. And want symfony to distinguish those 3 options:
my:command, which means something like my:command --arg=null
my:command --arg, which means my:command --arg=defalutValue
my:command --arg=someValue, which is fully explicit.
I.e. I want two working modes for code under that command: default one and non-default with additional argument, and that arg should have default value.
I understand, that I could create 2 args, but I'm looking for one-arg-to-rule-them-all solution.
Is it possible to accomplish that with built-in classes or should I create custom ones? If solution is only available with custom classes, please tell me, where to start (i.e. "create subclass of ..." or "install a bundle named ..."), cause I'm not familiar with Symfony2's architecture.
It is possible:
->addOption('arg', 'a', InputOption::VALUE_NONE)
my:command => $input->getOption('arg') //false
my:command --arg => $input->getOption('arg') //true
my:command --arg=5 => $input->getOption('arg') //5
Answer by corvax is incorrect and doesn't work. As of today, you just cannot achieve this.
It is even stated in the Console documentation: Using Command Options.
See also these issues on GitHub:
#8135 [Console] Input options with InputOption::VALUE_OPTIONAL and InputOption::VALUE_NONE not working as expected
#11883 [Console] Added three state long option
#12769 [Console] Ability to use option default only if the option was passed
#12773 [Console] Add method to know parsed option
Symfony2 have console component which can be used separately. You can see documentation here. For more example you can check implementations of SensioGeneratorBundle.

Rails 3 ActiveRecord::Relation random associations behavior

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

Resources