Add new model or extend existing one? - ruby-on-rails

Hi I have a model Workout and model Set.
Workout has_many sets, set belongs_to workout.
Set has certain properties, like number of repetitions for left hand, for right hand, total repetitions etc.
Now I'm in front of a dilemma how to create additional/different kind of sets with different properties (say set for time, set that goal is to reach certain number of repetitions etc.)
Should I extend set model and change form via javascript based on some choice (it would be easier with counting statistics out of sets but IMHO it would make validation more complicated) or shall I create new kind of sets?
Ideas/tips ?
Thank you
Petr

I'd create a new model but If they're similar enough I'd use Single Table Inheritance and simply inherit say the statistics methods from Set.

Related

Ruby on rails: What kind of object should I use when it doesn't represent the database?

There is something I don't really get with ruby-on-rails (I'm very new to it).
If my understanding is correct we use the model objects in the views.
The model object is the exact representation of the database. But in a lot of cases what we want to show in the view isn't the exact representation of the database.
Let's say we have an object line in the database:
line [line_id, quantity, category_id]
So if I want to show a list of lines there is no problem I can use the model object "line". But what if I want to show one line by category with a sum of the quantity for that category ?
Should I use the line object ? I feel bad about that because each line will not reflect a line in the database.
Should I create another kind of object ? Some sort of ViewModel that doesn't exist in the database but is usefull for rendering.
I'm not sure this is very clear... Thanks in advance for any help.
Always displaying data exactly as it is in the database happens only in tutorials :)
In real-world apps it is often necessary to transform data before presenting. This has many names: ViewModel (as you mentioned), Decorator, Presenter and others. So yes, make new objects for this, there's no reason not to.
If you display categories with a column in the view that shows the total quantity for each category, it would make sense to use the Category class in your application. This should be an ActiveRecord model.
On this model, you can define a method that reads the lines and sums the quantity. It could look like this:
def total_quantity
lines.map(&:quantity).sum
end
This method will read your lines (assuming you have set up a has_many :lines relationship in the Category class. Then it will read the quantity method on each lines and put the result in an array. Finally it will add the values together.
Note that this approach is a starting point and not very fast for larger sets of data. The approach can be improved through either lazy loading or specialized queries.
As your application grows in size, the number of methods such as the one above may grow in size to the point where the Category class becomes hard to understand. At this point, you may want to start looking for an intuitive ways to extract these methods into separate classes.

rails STI: specific attributes for subclasses

I'm starting building my first rails app and i already have user model with STI (admin, employee, public and representative all inherits from user model).
but now i want to add specific columns (adress, state, phone) for representative subclass but i cannot apply migration directly for subclass model.
the first solution is to add these columns tu user model but i don't know how th restrict acess to only representant subclass
the second solution is to create a separate contact table and and then use polymorphic association (i want to associate with other model) and add the attributes
my question is what is the best solution for this case? and if there is better solution?
Thanks
Hope you Doing well
I think second option is better then first.
Reason:
1) If this all filed are optional then it will create record with null value but in second case if all filed are optional then record will not be created,there is no need to any entry for that.
2) In future there is requirement of add or use this filed into other model then you can do by easily with polymorphic association .
It sounds like you are abusing the idea of an STI in this case. The general rule, is that you might have different associations for different child models and different behaviour BUT you ALWAYS have all the table columns used by all child models.
The whole Idea for why you would want to use STI is that all models contain the same structure of data, but maybe have different behaviours. In your case, I would suggest using associations (as you suggested yourself) and then add the has_one/has_many in the child model, which would limit the associations scope within the inheritance chain.
It is not possible to restrict columns to only some child models without patching ApplicationRecord. But in any case, even if you manage to make a patch to introduce this kind of behaviour, your database table will still have all the columns for all the tables, thus resulting in bigger database tables due to half empty columns, increased size and reduced performance.
I hope that answers your question.

Business logic dependent on model attribute

I have a User model that has an introduced_by attribute. Based on that attributes value, I calculate my commission differently. What would be the best, most flexible way of doing this?
Should I do a switch, or maybe put everything in a flat file? Also, should I create a Commission model?
It's a very broad question, as there is no code and no example. However, it seems to be the perfect case of a Strategy design pattern.
What I would do, is to create a class that represents the strategy for every specific range of attribute values.
E.g
PersonalCommission
CompanyCommission
HighValueCommission
DefaultCommission
Each class has a single method, let's say calculate that you can call passing an instance of the object and that returns the value of the commission.
Wherever you need to perform the calculation, just initialize a new Commission strategy object based on the User attribute and call calculate on it.
You don't even have to use a switch, as you can initialize the class dynamically.
strategy = "#{user.introduced_by}Commission".constantize
strategy.new.compute(whatever)
Of course, that's just a very simple example you'll have to adapt to your needs.

Should I use 2 models to store similar data but with different uses in rails

Hi there I'm currently in the process of planning a very basic rails app. I want to create small weight tracking app this will store a weight(number) within a Weight model there will also be the ability to add a goal-weight(number) every week a user would enter their new weight and it will be compared against the goal weight and show completion % etc to the user.
Now my question is would I have both a Weight model and a Goal model or should it be a single Weight model with some extra meta information to set a weight as a goal? I will admit im very much a noob with rails my gut says 2 models but I could be completely wrong.
This is a pretty subjective answer, but I would separate them for two reasons.
More modular. For example, you might want some model validations on Weight model, but not Goal model. In this case, it's easier to make them into two different models rather than have them in one.
Model associations. You may want to create model associations in the future.
Weight wouldn't even be a model for me, weight would be a parameter from user, as so would goal_weight. You could implement a method weight_over_goal_weight? afterwards to check if weight is over or equal goal_weight.

How do I handle a "fixed content" model in Rails?

In some of my forms I have to provide a dropdown where users can select some districts. The thing is, there will always be a fixed number of districts ( 31 in this case ). Should I create a model named District having only a string field,populate it with the data and be done with it?
It's content will not modify over time. Is there another way?
You should take a look at jnunemakers scam-gem. It mimics the AR for you and lets you define the models in your Rails app without a backing database/table.
I use this whenever I want something to do psuedo belongs to/has many relationships, but do not want to back a model with a database as the data does not change often, if ever.
Making a table-backed model is the simplest way. Otherwise you're going to end up implementing half of an AR model anyway, because you'll want to use collection_select at some point.
I guess it depends on how you want to store the districts and whether you want to do any querying etc.
For example, you could just have the list of districts as a constant, then store them as a string in your models (not very elegant), or as you say you could create a model and use active record associations - this would allow you to easily query on districts etc.

Resources