Serving alternate forms for editing one model in rails - ruby-on-rails

I have a model and I want to allow users to edit different subsets of the model's attributes at different points. Consider a model with attributes A, B, C, D, E, and F.
I would like to have the model initially created with a form that has fields for A and B. Then at another step in the process I would like to show the user a form to edit the model and have that form have fields for C and D and E. At another point I would like to show them a form to edit the model and have that form have fields for A, E, and F. My actual situation is more complicated than this but for the sake of this question I believe this is adequate. What are different good ways to serve up those different forms? The only way I can think of right now is:
Have a different action and respective form for each case and create the requisite routes in the routes.rb file.

Have you seen the Railscasts video that deals with multi-step forms?
I'm using a very similar implementation in my current project where a user can fill out their profile in parts...

John,
There are no restrictions on creating multiple views. You can create different partials or even full files and render them based on your own logic. The only practical issue you will run into is that of active record validations. You need a way to localize certain validations to certain forms. You can accomplish this using session, cookies et al. Another thing to look at it is whether you are collecting certain items only on :create, :update or some specific action method. If that is the case then you can use the ":on" qualifier to prevent the validations from firing at wrong time. The tutorial mentioned by Rob above is pretty good and I upvoted his answer. But it is one approach and you may find it easier to implement it in your own way using any of the other techniques I referred to.

Related

Splitting rails models vs. using one model for a combined form

I am working on an application that allows various people from different departments in a company log in and edit a form. Each department has specific fields in the form that only they are allowed to edit and view.
Would it be more organized code if I create one model for the entire set of fields and based on who logs in, render a different form containing the necessary fields? Or would it be better to split the department-specific fields into their own models and then based on who logs in, render a form containing their specific fields and relate the records from different departments together through a foreign key of some sort?
"It depends" is probably the best answer.
How many fields do you have? How much logic exists per department form type?
If you split all the fields to separate models (and corresponding tables) it will become a hassle if you ever want a full overview of the forms after they have been filled in, because they would be in separate tables. You'd have to go through every association of the form to get the full form.
If you still want to split them, because you have a lot of logic per department, you could point all your models to one 'main' table that contains all the fields, using table_name. That way you have all the data in one table and you can easily retrieve it. However, you'd also have to save the type of form in order to retrieve it in the correct model, probably more trouble than it's worth. (If it's the best thing to save all your fields in one table depends as well, how often does it get retrieved or does it get inserted/updated more often.)
Simple forms will probably fit just fine in one model. Unless you have a lot of non-sharable code per department it probably isn't worth it to split the form into separate models. If you do split the form into models you probably should create one main form model and have the department models extend it for whatever bit of reusable form logic there is.
After all that, I would say, I prefer simplicity so I'd probably save it in one model.
I'd split the fields and then you can setup your models with accepts_nested_attributes_for to build your form appropriately.

Assign attribute to object based on two fields of a form

I've got an app with illustrations that belong_to editions that belong_to novels. Currently illustrations do not belong_to novels, and I'd prefer if they didn't. On the form I can pass the edition_id when creating the illustration but can't figure out a way to pass the novel_id since it's not an attribute of illustration. I need to identify a unique novel edition pairing to create the illustration because many editions may have the name 1st, for instance, but different publication dates, etc.... I'm thinking I can make these a hash and then handle them in the controller. I don't know how to do that though. Is that the right approach? How do you make a hash out of 2 fields in a form?
Why do you need to do it from view?
If you need just pass to illustration novel_id, knowing edition_id:
#edition=Edition.find(params[:id])
novel_id=#edition.novel.id

Rails 3: What is the correct Rails way of doing custom types?

I'm doing a fairly complicated model on Ruby on Rails right now, and I was wondering what the correct "Rails" way of doing "custom types" for attributes was. For example, I have a table businesses which has a string attribute region. But region can only be one of a predefined list of possibilities (that could later be expanded). My question is: where do I define this Region type?
I know I could make a specific regions table (i.e. a Region model) which could house all the options, and then I could make an association between the models that have regions to that table. The problem is that I have many of these types on my model, so I would end up with more than half the tables in my database being "custom type tables" that only store the possible values for these types. Is that practical?
I also read that you could do this through validations (i.e. validate when saving a record, that the variables were within the possible values). This seems very impractical, since I want to make this model expandable, and form views would need to load the possible values of types into select boxes, etc. If I used this method, every time I needed to add a new possible value for a type, I'd have to change the validation and the views.
Is there a standard way of doing something like this? Something like defining types (maybe models without DB backing?) where I could list all the possible values easily?
Thank you for any help or suggestions on this. It's been bothering me for a long time while doing RoR apps, and I'm tired of hacking around it.
I guess there are many different ways to do it. Personally I would keep things very simple and DRY.
In an initializer, set arrays in the global scope:
REGIONS = ["region A", "region B", "region C"]
In the models, use validations as you wrote. Check that the value is in the REGIONS array.
In the views, use Rails helpers to populate selects, radios etc. from the REGIONS array. If you always have the same select, write your own helper region_select for instance.

Using multiple dropdowns instead of a text field in Rails 3

I'm currently building my first Rails 3 app, but can't quite figure out how to get one piece of functionality.
I have a temperature field, but rather than using <%= f.text_field :temp %>, I'd like to have two dropdowns. The first dropdown would allow choosing 97-99, while the second dropdown would allow choosing 0-9. After the user has made their selection and saved, the results should be concatenated into e.g. 98.2
What is the best way to achieve this in Rails 3? Thanks!
I suggest creating two virtual attributes, one for each part of the temperature (97-99 and 0-9). Then define a before_validation method on the model that takes those two values (that aren't persisted to the database) and sets the temp attribute accordingly (that is persisted to the database). This way you can validate the temp value as you normally would and query it as you would any other regular value in the database. It also keeps your view code easy on the eyes. There are other ways to accomplish this though.
Ryan Bates has a great screencast on virtual attributes.
http://railscasts.com/episodes/167-more-on-virtual-attributes
You could make two attributes in whatever model you use. One for each field you want to use. Then when you hit save you have code in the model and uses these attributes to form the temperature attribute.

Best practices for multiple models in rails from - nested / non-nested, and validations

Note:
Posting this as a separate question as per Brian's comment (from how to handle multiple models in a rails form)
I'm trying to learn the best way to handle multiple models in a single rails form, when the models are both nested and non-nested. For the nested ones, I found these two tutorials to be helpful
http://weblog.rubyonrails.org/2009/1/26/nested-model-forms
http://railsforum.com/viewtopic.php?id=717
My questions are:
In the case of a non-nested model, how to handle multiple entries for the second model? Just run a loop, and use fields_for?
In both nested/non-nested cases, how to validate for duplicate values, when there are multiple entries for the second model? For example, if project is the primary and task is the secondary (child) model, and the user adds multiple tasks for the project, how to make sure there aren't duplicate tasks added, for that particular model?
One way would be to loop through the text values, and check for duplicates. Is there a better way to do it, at the object level, instead of string level?
You might want to take a look at this to handle multiple instances:
http://railscasts.com/episodes/73-complex-forms-part-1
Also, I think I've answered your second question here:
validating multiple models in a rails form
You should have a look at the Presenter Pattern, it helped me a lot!
You can start here:
http://blog.jayfields.com/2007/03/rails-presenter-pattern.html

Resources