I think there are two sensible options. Either passing the user into a class set method (so UserSetting.set(user, name, value)) or better, put a method on user. e.g.
class User
def set(name, value)
setting = self.settings.find_or_initialize_by_name(name)
#...
setting.save
end
end
Usage:
user = User.find(1)
user.set("test", "foobar")
On a side note, "set" strikes me as a dangerous method name. I don't think it's reserved, but it's not particularly descriptive, and might clash with other stuff in gems etc. Maybe update_setting() would be better?
Finally, you could maybe do:
Class UserSetting
belongs_to :user
def self.set(name, value)
setting = self.where(name: name).first
setting = self.build unless setting
#...
setting.save
user.settings.set(name, value)
However, I think that's a horrible solution because it's relying on the set method being called on an association rather than itself. However, it most closes resembles your initial code, so I've included it as a possible solution. You might be able to go further and make it more sensible, but I think a method on user is better.
Does any of that help?
Jeremy Walker