How can I use activeadmin's has_many form builder with mongoid's embeds_many relationships? - mongoid

I'm using activeadmin 0.6.1, mongoid 3.1.5, and activeadmin-mongoid 0.3.0. embeds_many relations are arguably the best thing about mongoid, reducing the need for additional queries to fetch related data.
But I can't find a good way to make them work with activeadmin's f.has_many form helper (and activeadmin-mongoid doesn't seem to provide a f.embeds_many version).
The best solution I've come up with so far is to use a has_many relation, and use mongoid-alize to denormalize the has_many fields into the parent object. But this is somewhat unwieldy, as it requires me to access them as parent.children_fields instead of parent.children, which interferes with any code that expects an array of child objects instead of an array of attribute hashes.

Related

How do i model multiple photos (for a Hotel) with schema.org?

I am new to schema.org. Currently i am trying to use it as our internal data model for imports as it offers a good "common ground" for all source systems.
The Hotel schema (https://schema.org/Hotel) offers a "photo" (singular) property, it inherits from Place. It used to have a "photos" (plural) property in the past.
When using schema.org for markup, this would not matter, as i can just mark up multiple elements as "photo".
However, when using it as a data class, how should i model it?
Should i just make it an array of Photograph?
If yes, does schema.org actually assume on ANY property that it may be multiple (amenityFeature, availableLanguage, etc. suspiciously look like that)?
Does that mean, i have to actually model every property as an array?
After some additional research i have to assume schema.org is not meant as a full data model. It is mostly about providing a common vocabulary and a hierarchy of information. Its primary use case seems to be markup, so types definitions are very vague since they have to work on content that is actually meant to be presented to a user. So i will have to specify my own schema and let my decisions and my naming be guided by schema.org.

Does extensive use of ndb models affect performance?

I'm new to GAE and I'm still trying to figure things out. We're developing an Android app which uses Cloud Datastore to store images, videos, text, audios, etc. So we have now over 15 types of content objects.
I've been modelling each type of object as a distinct ndb Model class, but I'm wondering if this kind of design could affect performance.
Specifically, wouldn't it be better to write a simple class (e.g ContentObject) which simply had a content_type, and a few generic fields as string, number and blob?
I guess I'd go for the latter if I had to worry about creating/maintaining tables (or simply knowing that there are regular db tables behind).
I really like the first option, but I had to ask, just in case.
There are no performance differences to worry about between the 2 approaches.
With dedicated models you'll have to write a bit more code - each model needs to be handled separately. But it's simpler code, especially if eventually you will have some properties which only exist for some entities or are handled differently, which would require conditional logic with a generic model.
Building queries is also simpler with dedicated models if there are property differences, using a single model may require filling in unused properties (maybe by using default values) if they are used for sorting/filtering query results (entities with missing properties aren't indexed by the respective properties so they won't show up in the results).
On the other hand you'll need separate queries for each model, you can't obtain results for different kinds in the same query. And you'll need to maintain separate composite indexes for each kind (with a total limit of 200 such indexes per application).
If you're worrying about code duplication, which could also be a reason for which you'd consider a shared model, it's also possible to combine the common properties in a single ndb model class, with a single/common implementation for handling those common properties, and inherit that class in dedicated subclasses handling the differences. Something like this:
class Content(ndb.Model):
type = ndb.StringProperty() # not really needed, cls._get_kind() can be used instead
blob = ndb.StringProperty()
# other generic/common content properties and related methods
class Video(Content):
has_cc = ndb.BooleanProperty()
# other video-specific content properties and related methods
But this is just an implementation approach, from the datastore perspective you're still using dedicated models - in the above example a video entity will have a Video kind, not a Content kind.
There are no tables with the datastore, the only thing shared between entities of the same kind is their ndb model (which is specific just for the more performant ndb client library, other client libraries don't have one) and the search indexes definitions.

How to implement stack-like informations for a RoR model

i need to add to an "Event" model some information about "sub-events". For example, the Event might be a Match and a sub-event can be a goal (I need to track the striker too, and the minute), substitution or other. How is the best method to implement this? I think that is not a good solution to create a new Model for a Goal, I want that all the informations stay inside the Match model.
Maybe it can be done via "belongs to itself" association.
Look at this: Rails 3 - A model with a one to one relationship to itself - do I need belongs_to
The answer suggest using ancestry gem, or simple belongs_to association:
belongs_to :event, :foreign_key => "parent_event_id"
Also, in your model, you should add "event_type" column and put 'match', 'goal', or whatever you want here.
In my opinion it IS good solution to create Goal model, that would belongs_to a Match and a Striker and would store the information when it has happened (the minute).

Using a :reject_if to test uniqueness

I've been using accepts_nested_attributes_for with embedded models for a while. For mass assignment and ryanb's nested-forms gem it is practically required. Usually, it is used like this with a lambda function to verify the parameters hash so mass assignment doesn't fail with validation errors (while still being valid) if the user doesn't place any input.
class User
include Mongoid::Document
embeds_many :comments
accepts_nested_attributes_for :comments, :reject_if => lambda { |c| c[:comment].blank? }
end
class Comment
include Mongoid::Document
embeds_in :user
fields :comment
validates_presence_of :comment
end
What that does, I assume, with the :reject_if is remove the blanks from parameters before validation. What I want to do is evaluate uniqueness as well with validates_uniqueness_of and a lambda block.
I could loop through the comments (self.comments) but I assume there is some better way of doing this. I know that this would also cause uniqueness validation errors to fail silently but I am just wondering how it could be done.
The answer was half way down in the the related column here: validates_uniqueness_of in destroyed nested model rails
The validation can be modified to not add errors but to reject erroneous data. That will pass the uniqueness validation in the embedded model while stripping duplicates (with a message that that was done).

Rails - Big vs Distributed Tables

I am relatively new to Rails.
I have a User model through Devise. I am wondering if it is more efficient to have all the additional fields i need for the user, in a separate Profile model.
I am coming across similar situations where I am considering creating a new model and using a has_one association to that model however it seems like maybe it will be cleaner if I had all the attributes belonging to a user within the User model. How do you deal with such situations? What effect will it have on application performance?
Can someone elaborate on the advantages and disadvantages of creating has_one relationship, especially in terms of performance.
I am also relatively new to Rails as well, but this is my take...
The benefits of associations in Rails are pretty obvious I think. In this specific case I think you are fine to go either way. Here are some things to consider...
If you use a has_one relationship, you must remember that when you are referencing the profile you will end up with something similar to this:
user = User.first
puts user.profile.first_name
puts user.profile.age
Simple enough, but if you wanted something like user.first_name you would need to delegate that method to the Profile model. This is all a matter of preference.

Resources