Rails: model vs. array - ruby-on-rails

When should an array of values become a full fledged model? My problem is an application that is littered with models for such mundane objects as Country, Degree, Profession, etc. which are all simply parts of a user registration form. Should these constant arrays just be hard-coded or is there another better way to store them than using ActiveRecord models?

If it makes sense to have them as database tables, then it makes sense to have them as models. And I would argue that it does make sense to have at least some of these as database tables, because that way you can give your client the ability to edit them on-the-fly. I don't want a programmer to be responsible for maintaining a list of countries or professions.
(In a recent application I worked on that had an international focus, the ability for the client to edit the list of countries was a key requirement; in many settings, what countries are listed and what they are named have controversial political implications, so the client needed domain experts to discuss and decide on country names.)

Hardcoded Array is fine, creating a model for this is part of the antipatterns listed in 'Rails Antipatterns' from Chad Pytel

Related

What is the name of this concept I am implementing, and how to in Rails?

I am trying to implement a feature to my project (kind of like a social media site) that could be either basic or complex and I am not sure if I am going to take forever reinventing the wheel or just go on a crazy tangent that won't work. I just need to "check in" so to say.
I am going to use Facebook terminology as an example to simplify the concept but implement similar features with different names. In Facebook you have Pages and Groups, which are similar yet have slight differences (from now, I will call the collection of these DataSets). Both of these can have multiple admins or followers, which are all User roles, and each User can have roles for multiple Groups and multiple Pages (one role per Group or Page). Then for example, you can click a drop down to change your account to post as a Page you are an admin for.
Essentially, the concept I am describing is where a single User can have a role for multiple different types of DataSets. For example, a single User could follow 30 different Pages and 10 different Groups, and be an admin for one Group and two Pages. Does the concept I am describing belong to a particular concept or software design pattern? I am finding it really hard to describe this feature without using Facebook examples.
I have a strategy to implement this type of functionality in Rails, but I feel like using this strategy would be making the problem harder than it is and there is a fancy rails way of doing it, or a Gem, but I just don't know how to research it due to lack of terminology to describe my problem.
Current strategy is:
I have a Users table from Devise. Pages and Groups are each individual models and have their own tables. I have matching database tables to make the many-to-many relationships between Pages and Users, along with Groups and Users (e.g. 3 column design, column for the user_id, column for the page_id and the type of relationship such as admin or follower). Let's call these Group_User and Page_User. I am being flexible at the moment as I may add more DataSets similar to Page and Group.
Then for the Devise User table, I have an extra two columns to track the DataSet that the User is an admin for and currently posting as. One column is for the DataSet type and the other for the id for this instance (e.g. [Group,1] is stored in these two columns to represent Group with group_id:1 and [Page,3] is used to represent Page with page_id:3). These two columns can be checked when displaying options relevant for admins in that Group/Page and a simple drop down at the top of the site changes the values in these columns to any of the Pages/Groups the logged in User is an admin for. This way, one User login can take on many admin roles and change between these easily as needed.
Is there a better way to do this in Rails, such as a gem or specific design pattern? Or am I on track to implement these features myself? I think I understand the problem but my solution just seems simple/raw and possibly might have unintended consequences later down the track (e.g. it seems database intensive).
One way I was thinking of doing this was making a concern that includes methods to build the relationships and pass in the name of the DataSet as an argument, just so I am not rewriting the same methods for Pages, then Groups, then whatever comes next.
I looked at other solutions such as polymorphic typing (which I think is good for if each user only had one role or only managed relationships for one group or one page) and Single Table Inheritance (but I think my Pages and Groups might be too different for this to work). I thought about using inheritance as well (e.g. a parent for both Group and Page) but I am not sure this helps much.
I am just a guy that studied too much computer science and not enough software engineering. Any tips on how to simplify this problem or just a simple "yeah that will work" would be really helpful!
I think you are going great in the database design. Once participated in a social media application like yours which had similar type of design. Your design seems much better than the one I worked with. In my opinion this type of applications are supposed to be database extensive.
There are several design patterns used in RoR. One I heavily use is Service Object Pattern to maintain thin controller and models. Also it helps me to write reusable class.
Another one I like is the Presenter Pattern to simplify views.
You can have a details look at this blog post for more design pattern ideas.

Database design for reverse-auction platform

The idea is for a reverse auction platform where users post their auction for certain services and providers bid on it with their offers.
Should I be splitting my tables? For example the auction can be for a new service or to replace an existing service so there are questions that are specific to each selection.
Should I move those columns into a separate table for that option?
Here is a diagram of what I've come up with so far:
Database Diagram image
Am I on the right track here?
What data type should I use for columns where there will be an list of options to choose from in the auction form? For example, cash_back will give the user a range of choices as:
Donate to Charity
Deposit to my account
Credit Voucher
Is the norm to use a string for this column with the respective strings or do I create a new table for the options and use the option_id as a foreign key in this table?
I think it is worth discussing here Rails philosophy and database design generally.
As I often say you can have a database for your application, or you can have an application for your database. In the latter, database design is important. In the former, it usually follows application design.
What this means is that you probably, assuming this is a Rails app, don't want to design your database at all. What you want to do is design your application object model and let Rails design your database. You won't get a great db design that way, but it will be good enough.
The tradeoff is that when you go this way, you often end up with the database as effectively owned by the application and it may not be safe to have other apps add or modify the data in the database. Moreover it may be harder to come up with really good reports, but where you put in most of your time will be better optimized (your main app).
TL;DR: If you want a database for your app and using Rails or Django, then stop thinking about database design, but realize that while this optimizes some pathways today, it makes many other things harder down the road.

Rails 4 multiple similar models... STI?

I have 3-4 different types of clients for a photo site. Musician, wedding, portrait, and general with the possibility of adding more types. The idea is each type will have a shared set of attributes such as name email etc. but each will have their own too.
Musicians will have band name, members, genre, while wedding will have venue, coordinator details and so on.
I think this is the right way to go about it, correct me if there's an easier way to track multiple shared and unique attributes.
I was reading up on single table inheritance and one place said to use it only if the models have the same attributes but different behavior. How can I structure my models to meet this? From a more generic OOP standpoint this makes a lot of sense to me, but I'm having doubt's from that clause of STI.
Your use case sounds like a good one for STI. The key thing is that the children share some attributes with their siblings, not all attributes. I found this overview helpful:
http://samurails.com/tutorial/single-table-inheritance-with-rails-4-part-1/

How to Represent a Person Who is not a User in Rails

I'm trying to build a rails app similar to a CRM, where I have users, and each use has many "clients".
Initially, I created a model for a user and one for client, but while writing unit tests I realized these two are very much the same.
So my question is: was my original design decision to model them separately correct? Or is there a better way of reusing the code, even though I don't foresee Clients ever being able to actually log into the system?
I've looked at similar questions but they all apply to different user types and roles. In this case, Clients only exist as a model and will never actually BE users.
In any CRM application, User and Client there are similarities and differences between them. Let's put some details
The Similarities
Both of Users and Clients share various attributes, especially those related to personal information (name, contact info, ...etc.)
Both (mostly) represent one and only one person who has a relation to the system. One obvious exception are system users.
The Differences
A user accesses the system. This implies security needs such as authentication, identification and authorization, which in turn implies some validation (passwords, certificates, ...etc)
In CRM, a Client usually has various relationships such as with Account, Company, Team, Account Manager, and others, a User doesn't. Even though this is not handled by the model, but you might choose to do some model-level validations on some fields
Therefore, the choice of separating Users and Clients in two different models, combining them, or subclassing from a parent is a choice based on your actual need. There are some systems (such as OpenERP, if I remember correctly) treat Client and User in the same manner, while defining an is_system_user property. Personally I'd choose to separate them for the differences mentioned and for security reasons. If you're not sure about your need, it's safer (while not DRY'er) to separate them.
Maybe you should give a type to users (by creating a Type model and making a has_many/belongs_to ActiveRecord association for example): so a user can be a client or anything else you want.
Then, you can manage user permissions with cancan (a very great gem), depending of their type.

Modeling data for complex applications: inheritance? modules?

I'm developing a prototype for a Rails application that has a somewhat complex model. I'm having a hard time figuring out how the model should be designed.
Here's the basic idea:
Say the app is for a small coop, and should allow users to file "applications" (as in a apply for a loan, accounts, etc) online.
Technically, all of them are "applications" and my client would like a dashboard presenting all pending evaluations for a given group (ie: the auto loans group). So, I'm thinking of having an application model. I could subclass ApplicationModel for loans, accounts, etc., but I'm thinking Rails will use a Loans table, an Accounts table, and so, and so for each type of model. There are different kinds of loans too: Mortgage, Auto, Personal, etc. All require different data. A manager for the whole Loans division, should be able to see all pending loan approvals from his dashboard (all classes of loans).
If I were to do something like Loans.find() would I get all Loan subtypes with it? Or only what's stored in the loans table?
Is inheritance the way to go? Should I be looking at something else? Is rails even adequate for this kind of application?
I saw the legacy application built on Java that they were using (but hated with a passion). The previous developer had an ST_APPLICATIONS table which store all applications. In that table he stores all the application data in a blob containing a bunch of XML. Would such an approach be recommended with Rails?

Resources