How do I sort the rows in a nested object form in rails for just one view? - ruby-on-rails

When working with a nested model in a form, is there a way to sort the nested models in the view or in the controller? The closest answer I could find was here, but both of those solutions involve putting sort orders in the model. I'd rather avoid changing things fundamentally like that and keep this particular sort order to just one page.

You can always sort with ruby: parent.children.sort{|a,b| a.field <=> b.field} or something like that
Or you can add a find method to parent model, like def self.find_ordered_by_field
Can't think of another options...

Putting the sort in the models is absolutely the way to go. You shouldn't have any more ruby code than necessary in your views themselves, because it's much harder to test that your sorting is working the way you think it should.
When you add the sort at the model level (and either answer in the link you posted works well) you can add an automated test to verify that it is, in fact, sorting the way you'd like. This is business logic, and it belongs in the model.
Sometimes, however, you're looking to sort in a way that is NOT what you would normally want for this model. Maybe you normally want them sorted by name, but in this one view you want them sorted newest to oldest. At the very least, do the sort in the controller so once again it can be fully tested. But I would still put it in the model, personally.

Related

Filtering models using controller specific data

I have an application which is used by several divisions, where each of them has a separate set of data. So i got many models with a division_id field which indicates the division the row belongs to.
Each user has the division information also, so when they log in, i have to filter the data according to the division. So there are many places in my code where i do this for example:
Contact.where(division_id: current_user.division_id)
My question is how to refactor this code fragment? First i have thought about utilizing the default scope of the ActiveRecord, but since the division_id is a controller specific data, that didn't seem right. Any ideas?
I'm not sure why you say division_id is controller-specific data because it looks like you're getting the division from the User object (current_user.division_id). Anyway, the best thing to do would probably be just to make use of scopes here and then repeat the scope. For example:
# app/models/contact.rb
scope :for_user_division, -> user { where(division_id: user.division_id }
But it's still going to be repetitive calling e.g.
Contact.for_user_division(current_user)
everywhere. The main advantage is you can now change the rules of the scope in one place if you need to add something like only considering active? divisions later.
I don't think there's need nor want to DRY this up further. In general, I think default scopes are a bad thing because, in cases like this, a little bit of repetition is useful in reminding yourself what it is your'e dealing with -- a limited set of Contacts.
UPDATE
If you find yourself writing the same scope in more than one model then you can surely DRY up the scope by putting it into a concern and including it into each model as needed.

When should I create a model in MVC?

I am just getting started with ASP.NET MVC. So far I like it a lot.
I am trying to get up to speed but I need some clarification. I want to know when should I create a model for the logic.
I mean so many times I found my self putting all logic into one "master" model. I know its not the right way to go.
But then again I'm not sure if it is good to have redundant properties in my model.
I assume you are talking about ViewModels, and it is perfectly fine to have different viewmodels instead of having one complex model even the properties are repeating. With master model, it tends to get complicated down the road. However, for special cases like CustomerCreateVM and CustomerEditVM, I would create the commmon properties in base class CustomerVM and inherit it and for more readability I will keep them in one file. Does it answer your question ?
Your "View" model should accurately represent the information that is being shown/processed in that particular view. This means it should only have the fields that relate to the information being shown and nothing else. If it is not shown or used on the screen, it should not be in that model.

Where should I create an action to populate a select?

I'm quite new to Rails development and I came up with this question today. I have a method that returns some JSON data.
It is used to populate a select with a list of cities according to what was selected on a previous select (list of states). So, it's a simple method that loads a list based on some ajax parameter passed through and it is used all along my site.
I'm using Rails 4 and I placed this method on my HomeController. So everytime I need to fetch the list of cities, I call the HomeController to load the data.
Is this the correct approach or should I place this method on a more generic controller (like ApplicationController)? Is there a better way?
I think the best thing is to keep this modular. So you can create a separate controller for this, like StatesController - and possibly even a separate model if that makes sense for your application (I'm not sure where you're getting your data). There is no cost to having extra controllers, and this way your code is clean and organized, with each piece of functionality existing in its logical place.

How should I go about embedding a collection of new entities in a Symfony2 Form?

I need to write a form for creating a new entity and with it, up to 3 relations (which are new entities).
I can either have it dynamically attach/delete them dynamically (which could be useful) or have all 3 always be related to the entity, and for them to have an 'active' boolean on them, which would be just as appropriate.
At what point should I be doing this? I need them rendered as checkboxes on the form.
So far I've tried attaching them to the entity prior to passing it to the form, but choice fields can't be passed unmapped entities, so that's no good.
I've also tinkered with a DataTransformer for this, although then, as far as I can see, I would have to create new entities in the DataTransformer, which seems wrong, and I can't get to work anyway- I don't have access to the entity within it and even hacking around that, the relationship fails to bind properly (Doctrine tries to save the relationships first).
In Symfony1 terms, I could just embed a couple of forms for each additional relation I needed, using new objects, and it'd just work, so surely there's still a relatively easy way around this?
A friend also recommended looking into the ResizeFormEventListener, but this, as far as I understand, is for 'resizing' a form based on the returned data, whilst I never want the form to change, I want 3 checkboxes always.
What's the best way to approach this problem?
I'm not sure on exact details without playing with it - but based on how i've done similar things, i'd be looking to use a 'collectiontype' and then adding the three department types into that.

Order by association field using ActiveRecord

Is it possible to write an ActiveRecord query that sorts by an association field if the association exists, and otherwise sorts by an attribute on the object itself?
Example: I have a Discussion object which has_many :comments. I'd like to display a list of discussions sorted by discussion.latest_comment.created_at. However, some discussions may not have any comments, in which case I would like use their discussion.created_at attribute instead.
The catch is that I need the result to be an ActiveRecord::Relation (for performance reasons, and also because we are using Kaminari [which requires a Relation object]).
The only thing I could think of is to actually create a new field like discussion.latest_comment_at which would be initially populated by discussion.created_at and then updated every time a new comment is posted. However, this doesn't seem very straight-forward from a maintenance perspective (e.g. what happens when a comment gets deleted?).
I don't know of a way to do this through SQL, so I cheated and I have my code set a last_post_at attribute whenever a topic is created.
That way, I can then sort the topics by last_post_at rather than having to query two tables at once.
I've seen other forum systems do it this way too, and it seems like what you're designing is exactly a forum-like system.

Resources