5

I am in the process of writing a Ruby on Rails web application for my university's department.

For some of our resources in the web application, e.g. Project, are complex with their view layer logic:

  • a Project can be created by admin or faculty users.
  • after submission, faculty cannot update some attributes of their Project.
  • student users can view the project that they participate in, but can't update any attributes at all (view only).
  • new Project should hide some fields that are visible in the show action, because those fields are updated by an admin after submission of the form
  • many more rules...

Currently I have a single form for each type of action: new, show, and edit. The problem is that the business rules are lodged in the views in a very complex manner. I originally did this to prevent having a separate form for each user (that the controller would render based on the user's role), which had a lot of code duplication. The business logic will only get more complicated over time, making the single-form approach more complex to develop and maintain. But at the same time, separating out the forms into role-specific views causes an increase in code duplication.

So, on to the question. Would creating separate forms for each user role make sense, given that it would essentially be 50% code duplication? Is there a better solution that that?

The actual attributes that are allowed to be updated are actually controlled via Rails strong parameters and the Pundit gem which allows to scope resources based on rules (such as User.role). What I'm talking about is solely the presentation layer.

As an aside, I have already tried working with partials for shared form fields; however, I eventually need to move x or y field out of the partial and back into the complicated single form because some business rule changes to restrict access to certain fields to certain roles.

I have also looked at this MVC question which is pretty similar, but it's ASP.NET which might have a difference in how these rules could be separated out of the view; I've never worked with ASP.NET so I don't know. This general MVC question also doesn't answer my question; my business rules are already present in my models and through the Pundit gem; however, how to best present this data is not discussed.

1

In general, you want your business rules to be handled in your controllers or (even better) your models. View code should really only deal with displaying information.

Personally, I use the cancan gem to handle user authentication. Might be a good starting point for you. (Though it does sound like you'll need to do some refactoring.) https://github.com/CanCanCommunity/cancancan

Also, I'm not fully understanding your use-case regarding partials but there is rarely a reason to duplicate code. Realize that you can pass parameters into partials: https://stackoverflow.com/questions/6672454/passing-parameters-to-partial-view

With that in mind, you really should not have to duplicate any code. That is a big code-smell. If you find yourself doing that, it usually means you should rethink part of your design.

Hope that helps

  • I use Pundit to do access control, and it works fine. However, some views for say user with role student need to have some readonly fields in a resource that they can view/edit. The faculty user can edit those fields though, and the director can edit anything, and there are even some fields that need to be shown to faculty and students that only the director can edit. A single show action's view was 700 lines of code riddlde with if user.faculty? to show faculty-only fields, some were if user.director? || user.faculty? etc. Making changes was getting to be impossible. – Chris Cirefice Mar 17 '16 at 20:04
  • 1
    +1 Yes. First models. Then controllers. Basically not in the views, this you (Chris) need to fix. Several details in your question suggest that you have incorrect assumptions in application development. You can do this in the models and controllers and have very simple and reliable views. Your challenge is to use this approach. You might even consider a new application, using the same database but built out correctly from the start. Also, a simpler system like rails admin (a gem) might meet 80% of your needs better than a custom one that meets 100% but can't be maintained. – Michael Durrant Sep 13 '16 at 21:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.