Spent all day on Google, but can't find an answer. :\
I have a HABTM relationship between Users and Core_Values.
class CoreValue < ActiveRecord::Base
has_and_belongs_to_many :users
class User < ActiveRecord::Base
has_and_belongs_to_many :core_values
In my controller, I need to do two separate things:
For # 1, I've got this to work:
User.find(current_user.id).core_values.create({:value => v, :created_by => current_user.id})
This creates a new CoreValue with :value and :created_by and creates the association.
For # 2, I've tried a few things, but can't quite seem to create the association ONLY.
Thanks for your help!
The basic structure of a polymorphic association (PA)sets up 2 columns in the comment table. (This is different from a typical one-to-many association, where we'd only need one column that references the id's of the model it belongs to). For a PA, the first column we need to create is for the selected model.
Self-referential association means we create a JOIN MODEL, such as Friendship, for example, which links another model, such as User to itself, so a user can have many friends (which are other users), and a friend can be befriended by a user ( a follower and a followed).
You can do this in a two-step procedure, using the very useful find_or_create
method. find_or_create
will first attempt to find a record, and if it doesn't exist, create it. Something like this should do the trick:
core_value = CoreValue.find_or_create_by_value(v, :created_by => current_user.id)
current_user.core_values << core_value
Some notes:
v
. If it doesn't exist and is created, it will set the created_by
to current_user.id
.User.find(current_user.id)
, as that would return the same object as current_user
.current_user.core_values
is an array, and you can easily add another value to it by using <<
.For brevity, the following would be the same as the code example above:
current_user.core_values << CoreValue.find_or_create_by_value(v, :created_by => current_user.id)
Add a method in your user model:
class User < ActiveRecord::Base
def assign_core_value(v)
core_values.find_by_name(v) || ( self.core_values <<
CoreValue.find_or_create_by_name(:name => v, :created_by => self)).last
end
end
The assign_core_value
method meets requirement 1,2 and returns the core value assigned to the user (with the given name).
Now you can do the following:
current_user.assign_core_value(v)
Note 1
Method logic is as follows:
1) Checks if the CoreValue is already associated with the user. If so no action is taken, core value is returned.
2) Checks if the CoreValue with the given name exists. If not creates the CoreValue. Associates the core value(created/found) with the user.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With