-
Notifications
You must be signed in to change notification settings - Fork 93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mutations with forms in Rails (2.3) #65
Comments
Hello, I've been looking at this gem to use in a normal Rails app and your post is very helpful @6twenty. Because having mutations work with the Rails form helpers is pretty important. Could you say how this design has improved your code? I assume your models don't have any validations. Is testing easier? Is the code cleaner? Etc. I'm one of those people who has somewhat rejected the "Rails Kool-Aid", but nonetheless I'm practical, and model validations is probably one of the parts of "the Rails way" I'm OK with. And one can pull out of a lot of business logic into Plain Old Ruby Classes without necessarily using this gem. |
@leavengood we implemented this as part of a refactor for a specific area in our app. We had fallen into the very traps described in @cypriss's post introducing Mutations: we had a fat model with several virtual attributes which were being set via form params and handled using ActiveRecord callbacks. This (as the post says) sucked. The callbacks lost almost all context and had to re-determine the current state of the model before handling the changes correctly.
The refactored code is wonderfully simple, which is a pleasure since the previous code was quite complex. We ended up with ~10 mutation classes each with a very specific role. This led to some code duplication and probably more lines of code overall, but the code is significantly cleaner and vastly more maintainable. Our models still have the usual validations -- we deliberately tried to leave the models as un-touched as possible because the refactor only focussed on a specific area of logic. The only changes on the model were to remove the relevant virtual attributes and callbacks.
As you can imagine testing mutation classes is extremely simple. In contrast to testing virtual attributes + callbacks, our test suite is much cleaner (and faster).
This entered my mind as well, but to be honest we likely would've ended up with something very similar to this gem anyway. No need to reinvent the wheel. |
@6twenty Thanks for the feedback. We already started using mutations in our project and so far so good. We even have a few small fixes and improvements to do as pull requests. I've been thinking that leaving basic validations on the models is fine and the use mutations for more broad-scoped work. It sounds like that is mostly what you have done, so that is good to know. |
This isn't an issue or a question. This describes how I have integrated Mutations into form views within a Rails 2.3 app. This could be a discussion on how Mutations could evolve to have wider uses within Rails, or it could just be a reference for others looking to implement their own similar solution. This is a bit of an experiment, but comments & feedback are welcome!
This is what my controller actions look like:
Note that on the mutation class I initially call
new
rather thanrun
; this allows me to bind the Rails forms to the mutation rather than an ActiveRecord model. I am also passing in an ActiveRecord model as the first parameter on theedit
, andupdate
actions, which assigns attributes to the mutation straight from the model (more on that below).In my views I then use
form_for @mutation, :url => some_path
(the:url
is required here, although I suspect it would be possible to extend the mutation class to allow Rails to deduce the url).My mutation classes are mostly unchanged, but with a few additions. Here's an example of the
CreateMutationClass
.The
required
&optional
blocks, and theexecute
method, are all standard as per the mutations docs.And the
UpdateMutationClass
:use :new_record_mocks
anduse :existing_record_mocks
each set up the following methods:id
,to_param
,new_record?
and_destroy
. These allow Rails to render the form properly.use :model_name
simply changes the input field base name, defaulting to'mutation'
.use :base_model
allows linking the mutation to an ActiveRecord model. This redefines thenew
method to allow the first parameter to be an ActiveRecord model of the expected class. By default the mutation attributes will attempt to get their value by calling a method of the same name on the model, however using a base model also allows using themap
method to handle non-matching attributes. Passing in multiple parameters still works the same way (subsequent hash parameters will override existing attributes).And here's the
MutationExtensions
module:@cypriss, I'd be interested to hear your thoughts on moving towards wider Rails support so that mutations can more easily apply to UI apps as well as APIs. I'm aware that there are other similar gems out there which integrate with Rails forms, but I've so far enjoyed working with mutations the most :-)
The text was updated successfully, but these errors were encountered: