Open leehericks opened 6 years ago
Firstly, sorry for not responding sooner!
I didn't actually know about assign_attributes
in ActiveRecord
or ActiveModel
, but I'm always happy to have more things in ActiveModel
that we can take advantage of.
When you mentioned assign_attributes
, I wondered if it was calling #write_attribute
for each key / value pair or if it was calling the #key=
method. Looking at the code, it seems to be the latter:
Also, since I was unfamiliar with assign_attributes
, I didn't realize that the neo4j
gem was defining it (see this bit of code). The code looks to be about the same, so we could probably drop our implementation and replace it with include ActiveModel::AttributeAssignment
. You could simulate that for now with:
Neo4j::Shared::MassAssignment.send(:remove_method, :assign_attributes)
class YourModel
include ActiveModel::AttributeAssignment
end
I suspect that won't fix your issue, but it's a good place to start to figure this out.
Actually... Looking at the neo4j
implementation I'm noticing that if the attribute isn't defined we call add_undeclared_property
which has an empty definition unless you include Neo4j::UndeclaredProperties
. So that could be tricky... Heads up to @klobuczek since he put in the UndeclaredProperties
module. Perhaps it makes sense for us to still include ActiveModel::AttributeAssignment
but provide our own implementation that calls super
and rescues from ActiveModel::UnknownAttributeError
Ultimately, though, if there's still a problem I think it might not be the fault of assign_attributes
but rather the association code since assign_attributes
is really just calling association=
. If this acts differently than ActiveRecord
then we should definitely investigate it (though it would be a breaking change, and potentially a big one)
Thanks for investigating this.
Yes, it seems simply to boil down to associations being saved automatically, which is not always desirable. I may wish to assign the properties and associations and call valid?
for instance. If there were some errors in my form for properties, of course, I would't want those associations created yet because I will reshow the form with errors and it is unknown if the user will correct the form and submit again.
I think assign_attributes
and assignment in general offers the ability to run validations, examine the dirty state of the object and conditionally persist or take some other actions, so I can only think of two ways to correct this:
In the case of (1), I personally think of properties and associations the same way. The are assignable and accessible values. In this case I don't think their persistence model should differ, ESPECIALLY since they get assigned together through the attributes methods.
As for (2), it is a non-breaking solution but again something that Rails programmers might not be used to. Perhaps has_many :out, :things, persist_on_assignment: false
because ActiveRecord has the option :autosave which may be confusing.
:+1: I think if we had associations automatically saving it was because we thought that that's what ActiveRecord
did. I'm happy to take their guidance on how to implement this whenever it makes sense for Neo4j
I'm running into this issue as well. Any word on this being addressed?
@klobuczek @amitsuryavanshi I vote for prioritizing this one.
According to Neo4j.rb documentation here, setting associations saves automatically.
In Rails 5, AttributeAssignment was moved from ActiveRecord to ActiveModel as mentioned here.
Therefore, ActiveNode has the following methods:
The problem is that
assign_attributes()
andattributes=
are not supposed to save or call any validations. Good Rails 3/4 usage explanation hereIn my Rails 5 project, using mass assignment from a form causes the associations to persist immediately, which causes issues with setting attributes and checking for changes as seen in the following code:
Of course
update_attributes()
is documented to run validations and save the model and this is where associations persisting is acceptable and works correctly.Rails 5.1.4, Neo4j.rb 9.0.7, Neo4j 3.3.0