Ruby on Rails: Scope vs Helper Method - ruby-on-rails

I'm pretty new to Rails and wanted to do something along the lines of choosing a subset of objects in my Model. For example, I have a Project model and wanted to select some subset of projects based on some join table with another model, Organizations.
My initial thought was to create some helper method in projects_helper.rb that would perform the appropriate lookup on to determine which projects to return.
Another thought was to utilize scoping as described here (http://apidock.com/rails/ActiveRecord/Scoping/Named/ClassMethods/scope).
Both seem to functionally complete the objective, but what would be the best practice way of accomplishing this? Is there a key difference as to what can access each of these approaches?
Thanks!

Depends on the point of view of the question being "asked" by the query.
If you are asking for an Organization's projects, you might choose the Org first, then display organization.projects. Nothing fancy going on there beyond linking the models appropriately (organization has_many projects, project belongs_to organization) and having the organization_id as a foreign key in the projects table.
I'm not sure if a named scope would be appropriate if the Organizations in your system are a dynamic quantity. You don't want to have a named scope for each if the list of organizations changes all that often.

Related

Should I use Multiple user models or one big user model in Devise

I'm doing a Rails project with three user types: students, teachers, and administrators. Each user type has a dozen+ columns unique to that role. Initially I thought I'd create separate models for each type, but having a single shared login seems to pose a problem (I've found a workaround on Stack Overflow, but its complex and a few years old).
What is SOP for situations like this? Is it kosher to have a single user model with 24+ columns that will always be empty depending on the role type? Or am I better off sticking with three separate models and trying to hack a workaround to make a shared login?
Thanks!
EDIT: Oops, forgot to add the third workaround which I'm favoring: having a single user model with only columns relevant to login, and then models for each role that hold columns specific to each user type. Is that a good call?
You could make two separate models, Student and Teacher. Then add an admin:boolean field for teacher. I am assuming most admins will probably be teachers? Even if that is not the case you could just default that all admins are teachers. Three separate models is terribly bulky.

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/

Should I use polymorphism to model these relationships?

I'm working on an app with Project, User, and Group models. A Project has many groups, a User belongs to many groups through a Membership model. I have two choices:
When a Project is created, a default group is created. Any person participating in this project is automatically added to it.
Make Memberships polymorphic so that users can be a member of a project, and a group in the project.
Both approaches have wider implications: Other models will come into play, such as: File, Post, and Task.
If I go for option 2, those models will also have to be polymorphic. But it would simplify things a bit.
If I go for option two, I forgo polymorphism, but things get a bit complicated. For example, finding the users projects means I have to query for the user's groups, then projects associated with those groups, and then make sure the projects are unique.
Has anyone faced a similar situation, any advice or additional pros and cons for either approach?
I really would rather ditch groups altogether, but it's a requirement for permissions, to separate content based on group.
I think best option would be creating a default group, because:
Then you can go with a clear structure:
projects - has many groups
groups -> has many users etc,
you will have the flexibility of managing groups easily
your core structure is simple, hence years down the line, easy to expand
you are easing the work flow of user by automating a one step. I personally believe if you could let a user to up and running quickly, they will find your system user friendly

ActiveRecord relations between models on different engines

I'm building a Rails app that is probably going to have a large amount of models. For now let's say that i need to have Users, and each User will have a personal Blog
I've been developing the User-related part on a separate Engine (let's call it AuthEngine) that encapsulates the User model, authentication, etc. At the time this seemed like the best approach
In parallel, my colleague was developing another engine, to deal with the blog features (let's call it BlogEngine).
Now he needs to access user data which is stored in the other engine. He achieved this by defining:
BlogEngine.user_class = "AuthEngine::User"
This way, he can easily ask for user data, even though it isn't stored in the same engine. The problem comes when we want to define relashionships between models
He can easily say that each blog post belongs to a user
has_one :user, :class_name => BlogEngine.user_class
But as far as i know he can't specify that each User has multiple posts since the User model is within the other engine
The consequence of this is that he can't do things like #user.posts, but instead has to do Post.find_all_by_user(#user)
Is there a more elegant way to deal with this?
I also considered the possibility that each engine could simply generate the models inside the app, removing the encapsulation, but since the amount of models will grow quickly, i think this will make the app more of a mess, and not as much maintanable
I think you should reopen user class inside blog_engine in order to define has_many :posts relation and it should be appropriate way.
What about having a common models gem/engine with only the relationships as a dependency for your engines? This way you would have access to all relevant relationships in every engine.

RoR table inheritance?

Scenario: I have a users table in my application. I also have two subclasses of users, lets say contributors and viewers. Each user group must have an entirely different set of attributes but they both share certain user properties (login, password, name).
What is the best way to implement this using Ruby on Rails?
I think single table inheritance would leave me with too many null fields.
I think linking three tables (users, viewers, contributors) would work fine, but then when wanting to edit any information i have to do: #user.viewer, while i would love to be able to just do #viewer.
Any ideas of the best solution?
I would probably go with the three tables approach. Data integrity is king over code cleanliness.
If you want to make it look neater, put virtual attributes on the Viewer and Contributor models that make it look like the User attributes are local. You can make it a module and include it in both Viewer and Contributor models.
You can also set up an :include => :user on the default finders so that you don't get an extra query when using those fields.
I'm extremely caffeinated right now, so comment back if that doesn't make sense :)
don't compromise the database schema, make it fit best. I like the three table method. If you do the database bad, the application will have very hard to fix issues later, run slow, etc.

Resources