Inheriting the Rails Model in Forms

I use the reporting system for my application. For example, I created the ReportKind model, but since I can report a lot, I would like to create different groups of report types. Since they have a lot of behavior, I am trying to use inheritance.

So, I have a basic model:

model ReportKind << ActiveRecord::Base end 

and created, for example:

 model UserReportKind << ReportKind end 

In my report_kinds table, I have a type column, and so far everything is not working here. My problem is with forms / controllers.

When I do ReportKind.new , my form is created with the prefix '* report_kind *'. If you get UserReportKind, even through ReportKind.find , the form will build the prefix 'user_report_kind'.

This is a mess in the controllers, as sometimes I will have parameters [: report_kind], sometimes params [: user_report_kind], etc. for every other inheritance I made.

Is there a way to force it to use the prefix 'report_kind'? I also had to force the “type” attribute into the controller because it did not get the value directly from the form, is there a good way to do this?

Routing was another problem as it tried to create routes based on the names of the inherited models. I overcome this by adding other models to routes pointing to the same controller.

+6
inheritance ruby-on-rails activerecord ruby-on-rails-3 forms
source share
1 answer

Such inheritance is always difficult. Fortunately, the problems you are talking about are solvable.

First, you can force forms to use specific attribute names and URLs, for example:

 <%= form_for :report_kind, @report_kind, :url => report_kind_path(@report_kind) %> 

This will force all the parameters for @report_kind to be in the [: report_kind] parameters, regardless of whether @report_kind is a UserReportKind user or not. In addition, all post and put requests are also sent to ReportKindsController.

Secondly, you can specify a type with a hidden attribute like this:

 <%= form.hidden_field :type, 'UserReportKind' %> 

Finally, for routes, I would do the following:

 map.resources :user_report_kinds, :controller => :report_kinds 

This means that any URL, such as / user _report_kinds / ..., will use ReportKindsController.

+6
source share

All Articles