Rails Braintree gem subscription class conflict - ruby-on-rails

In my Rails app, I'm using the Braintree gem to create subscriptions. Without realizing, I had also created a Subscription model and controller to manage the subscription info I wanted to store locally. In my model, a subscription can belong_to a user. However, some of the normal stuff you can do wasn't working such as
current_user.subscriptions.build()
But for some reason when someone was helping me they were able to use
current_user.create_subscription
Where is this create_subscription method defined? Is it somehow overriding the Rails convention?
I noticed that there is a subscription.rb file in the Braintree gem. Is there some conflict with the class defined by Braintree and my Subscription model? I know that I can probably just rename my Subscription model, but I'm curious as to what the conflict is.

Your issue is that the subscription relation is has_one or belongs_to, rather than has_many. User would not have a subscriptions method in this case as the attached subscription would be singular. Review the API docs for how to manipulate these sorts of relations in AR.
From the manual on has_one:
The following methods for retrieval and query of a single associated object will be added:
association(force_reload = false)
Returns the associated object. nil is returned if none is found.
association=(associate)
Assigns the associate object, extracts the primary key, sets it as the foreign key, and saves the associate object.
build_association(attributes = {})
Returns a new object of the associated type that has been instantiated with attributes and linked to this object through a foreign key, but has not yet been saved. Note: This ONLY works if an association already exists. It will NOT work if the association is nil.
create_association(attributes = {})
Returns a new object of the associated type that has been instantiated with attributes, linked to this object through a foreign key, and that has already been saved (if it passed the validation).
Braintree does have a Subscription class, but this is namespaced to Braintree:Subscription so it is not the issue.

Related

access ActiveRecord Has Many associations

I have a model which has a lot of associations. What I need to do is to check whether one of those associations is not present or all of them are set correctly.
To do so, I created an array which includes all of those needs-to-be-checked fields. And created a loop through each element, but the case is that I can not access has_many related attributes with read_attribute method. It basically returns nil whenever I try to access has many associated fields.
What I am trying to do, I can access all related objects via car.drivers but I can not access the same object with car.read_attribute(:drivers) (because some of them are attributes and some are relations)
I think it's the behavior of read_attribute, so what should I use to access any (attribute or relation) on ActiveRecord object?
Regarding to the comments, it looks like no one understand what I am trying to do. I want to access the relations of one ActiveRecord object such like;
RELATIONS.each do |relation|
puts "#{relation} exists" if #object.relation.present?
end
What I do not know about this, is there any method that I can access the related objects with their string typed name. Similar to, #object.read_attribute(:attribute_name) In that way I can create a for loop, but for relations not for the attributes
To do so, I used dynamical method call. Below is an example of showing it
RELATIONS.each do |relation|
puts "#{relation} exists" unless #object.send('relation').nil?
end

Overriding shovel method in rails in association case

According to the has_many documentation, the "shovel" method collection<<(object, …)
Adds one or more objects to the collection by setting their foreign keys to the collection's primary key. Note that this operation instantly fires update SQL without waiting for the save or update call on the parent object, unless the parent object is a new record.
If you want to construct a new-record without saving it to the database just yet, use collection.build.
Returns one or more new objects of the collection type that have been instantiated with attributes and linked to this object through a foreign key, but have not yet been saved.
Using Club and Member as example models:
club = Club.find(params[:id])
club.members.build(member_attributes) # member is not saved
club.save # saves club and members
BUT WHAT IF
I would like to use << to create associations and not firing SQL at all. How can I override << to behave like in scenario when the parent object is a new record?

What does "the customer is eager-loaded automatically when it's needed." mean?

I don't understand this part of this page on RailsGuide.
There's no need to use includes for immediate associations - that is, if you have Order belongs_to :customer, then the customer is eager-loaded automatically when it's needed.
What does "the customer is eager-loaded automatically when it's needed." mean?
When the instance(s) of order (from Class Order) are retrieved from the db, due to the foreign key relationship to it's customer, their is a strong likelihood that you will use this relationship, (i.e. order.customer.last_name.) Because of this, ActiveRecord automatically retrieves (and builds) the customer instance so it will not have to go back to the db again when you use the relationship.

How can I get a list of the associated models that were updated during the save of an instance of ActiveRecord?

I'm passing params to a model instance and saving it with update_attributes. It is associated with several other models and I've configured it to update some of these with accepts_nested_attributes_for.
This is very nice and clean as I only have to update the one model, but I'd like to get a list of the associated(nested) models that were also updated so that I can give the user feedback about some of the fields that have changed.
Is there a way to do this, or am I approaching the problem in the wrong way?
I've found a solution to my question, maybe not the best one but it will work.
For a list of models that are associated and have accepts_nested_attributes_for configured we go:
associations = ModelClass.reflect_on_all_autosave_associations()
Each of these association objects has a name attribute(the association name), which can be used to access the association on the instance, and then we can check whether this association has changed:
associations.each{|assoc|
model_instance.send(assoc.name).changed?
}
It should be noted that we cannot use update_attributes with this solution, as all the models are saved before we can check whether anything has changed. So we have to assign_attributes and save the model in separate steps:
model_instance.assign_attributes(params[:model_instance])
// check for changes on associations here
model_instance.save()

Rails 3 Polymorphic Association between one MongoMapper model and one/many Active Record model/s

I have a Record model (Active Record) that stores some custom logs.
Record is in polymorphic association with all the other model in my app, and I can effectively log what I want hooking my Record methods in the other controllers.
What I need:
To have the logs in a separate database.
So I have to:
Be able to manage two different databases in my apllication (one is Postgres/ActiveRecord and the other one is MongoDB/MongoMapper)
Generate a polymorphic association between my Record model, now with MongoMapper, and the rest of my Active Record models.
That way I can persist my logs to the MongoDB database.
Thanks.
Yes this can be done.
To create a polymorphic association you need both the class and an id. Idiomatically the fields will be named <assoc>_type and <assoc>_id‡. You will need to do some wiring up to make everything work.
Create a MongoMapper::Document Class with the keys <assoc>_type and <assoc>_id with the correct types (I believe MongoMapper allows Class as a key type) along with any other keys you may need.
Define the method <assoc> and <assoc>=
def assoc
assoc_type.find(assoc_id)
end
def assoc=(input)
assoc_type = input.class #STI makes this more complicated we must store the base class
asspc_id = input.id
end
Possibly add a method to your ActiveRecord models allowing them to access you MongoMapper logging class. If there are a lot, you may want to build a module and include it in all the classes that need that kind of functionality.
‡ replace with something meaningful for you application like 'reference' or 'subject'

Resources