How to serialize virtual attributes in rails 5 - ruby-on-rails-4

I want to searilaize a couple of virtual attribute defined in my model like below
class User
attribute :full_name, :string
attribute :mobile, :integer
serialize :properties
end
I wants to save full_name and mobile in hash format in properties column of users table. How can I do that, Please help.

If you need to save those two attributes in your properties column you'll have to first make sure that your properties column is a text column. Then add the following to your User model.
serialize :properties, Hash
Then add a callback to make sure that the attributes are built correctly:
before_save :serialize_properties
private
def serialize_properties
properties = { full_name: full_name, mobile: mobile }
end

Related

Django SimpleHistoryAdmin How to Change Custom Column Name

In Django SimpleHistoryAdmin List View are 5 default columns (OBJECT, DATE/TIME, COMMENT, CHANGE_BY, CHANGE_REASON). I may add another column adding it to the history_list_display but name of this additional column is displayed as it's name in code, for example first_name. Is there an easy way to display it as First Name?
the column will show the verbose_name defined in the field definition on the Model.
If you do not have access to the Model but to the ModelAdmin, you can try to do something like:
class SimpleHistoryAdmin(...):
...
def _myfirst_name(self, instance):
return instance.first_name
_myfirst_name.short_description = "DESIRED FIELD LABEL"
You can user gettext and it's variants to provide translations for your custom label if needed.
Hope this helps.

Django User Model with ManyToMany relationship, how to update/ create new profile with relationship?

I have a class that has a one to one relationship with my User class. In this class (called UserLocations), I have a field that is a ManyToManyField on another class (we will call this model Locations).
In my Locations class, I have a field called 'abbreviation' which is a four character abbreviation of the location name. I have a front end website where an admin can create a new user or update an existing users locations (based on the abbreviation field).
When I am going to create a new user, how would I set/ update that ManyToMany field based on the 'abbreviation' field? It is a list of abbreviations that tie to that 'abbreviation' field in the Locations model.
# Assuming you get the chosen abbreviation in a variable called location_abbreviation:
desired_location = Location.objects.get(abbreviation=location_abbreviation)
user = User.objects.create(...)
user_location = UserLocation.objects.create(user=user, ...)
user_location.locations = [desired_location]
user_location.save()
Let me know if I misunderstood your question.

In Rails 4, how should a controller take a parameter to specify an associate by a non-id field?

Each Widget has an associated User. Users have a String attribute called email which stores the email address associated with the User.
The User model has a unique id attribute, as per Rails conventions, but also ensures that email addresses are unique. Therefore, User.where(email: foo#example.com) is guaranteed to return at most one result.
In a form to create a Widget, I would like users to be able to specify an email address, rather than an ID. Both id and email are unique keys for Users, but email addresses are more convenient for people.
What's the recommended way for the Widget controller to accept an association reference that names the associate by a key other than id? When using id, if the widget[user_id] parameter stores the ID for a User, mass-assignment (in create or update) stores the correct User in the Widget. Is there any built-in Rails support for making something like widget[user_email] work, or should I add code in the controller to recognize that parameter, look up the User, and associate the User with the Widget?
Here's the code:
class Widget < ActiveRecord::Base
has_one :user
end
class User < ActiveRecord::Base
end
class WidgetsController
load_and_authorize_resource
def create
#widget.save
end
def widget_params
params.require(:widget).permit(...)
end
end
I've considered:
Modifying the Widget model to add a setter for "user_email", looking up the User there, and setting "user_id" appropriately.
Modifying WidgetsController#widget_params to notice the presence of "widget[user_email]", look up the User, and replace it with "widget[user_id]".
I'm leaning towards the second option.
Is there a better way?

Rails: Best way to allow a user to set a default resource

I have a users and venues model. venues belongs_to users and users can have_many venues.
I would like a user to be able to set a default venue. I am new to programming/development and am keen to learn best practices.
So, should a venue have a boolean 'default_venue' column which only allows one row to be 'true' per user. Or should I be creating a default_venue model? And if so, any tips on what/how this would look like?
I would just add a default_venue_id to the Users table. Then write a small method on the User model.
# User.rb
...blah blah validations
...blah blah other code
def default_venue
Venue.where(id: default_venue_id)
end
Then going forward in your Controllers (or Rails Console), this would be valid code:
#Returns default venue for User
User.find(:id).default_venue

How do I set a field named by a string?

For a view that updates a model, I'd like to do something like this:
for field in ('name', 'parent', 'notes'):
if request.POST[field]:
myModel[field] = request.POST.get(field, '')
However, model's fields are accessed as properties (myModel.field), not dictionary items, and as far as I can tell there aren't get/set methods in Django models. Is there another way I can update these properties iteratively?
setattr()