A default flag on a table in rails - ruby-on-rails

I have a simple table/model in rails, vat_rates. Administrators need to be able to select one, and only one of these as the default rate that will be selected on the HTML form when creating new related items items that have a vat_rate_id. I have added a boolean default column to the vat_rates table.
What is the most straight forward, and rails-like way to ensure that only one vat_rate can be the default one at any time?
I'm not really bothered if there are no defaults, just that there are no more than one.

You could add a custom validation method like this and return an error if another vat_rate is selected as default already. Alternatively you can add a before_update or after_update callback like this to set all other default values to false on update.

Related

updating a model while in before_update

I've been wondering, suppose I have a model with an attribute that in every instance is dependent on that same attribute in other instances. The best example for this would be an order attribute for items in a list.
The best place to update the rest of the items' order attributes would be in a before_update callback method, were you have both the item's old and new values.
But now whenever you update the other items in the list the callback is going to be called again, and again...
I'm looking for an elegant way of solving this.
I have heard about the :update_without_callbacks method, but i don't want to use a private method, and also i feel like adding extra attributes would be unnecessary.
Got any good ideas? Thanks in advance!
One way would be to use update_all to set the order of all the other items in bulk.
That way you would efficiently limit the number of queries to one and prevent any callbacks from being triggered.
https://github.com/rails/rails/blob/83e42d52e37a33682fcac856330fd5d06e5a529c/activerecord/lib/active_record/relation.rb#L274
I feel the fact that you have to do this type of update across entries suggests you haven't properly conceptualized your problem. Why not create a List model that has the order attribute, and then create a one-to-many relationship between the List model and the Item model. This way, there's only one place to update the ordering information and no need for complicated and brittle callbacks.

ASP.NET MVC Using view models in different views

I have 2 customer views one for create and one for edit. I am using the same customer view model for both. I want to make the 'customer no field' required on the add, but not the edit.
If I put the requiredfield attribute on the view model property then both views flag 'Customer No' as required (as you would expect).
Is there a built in solution to get around this problem or Am I going to have to create 2 seperate view models, one with the attribute and one without.
Thanks
This is similar to this question.
I would strongly advise you to tailor 2 View Models for edit and create actions. It is a lot cleaner. The last answer in the link I gave you makes a workaround and disables the errors on the ModelState.
How is Customer No. required on create but not edit?
If you create it, it requires the number, and when you edit it, the number is still there.
Do you mean they can remove the customer number on edit? Or do you mean you want Customer no. to be non-editable on edit?
If it's the latter, then you can keep customer no as required, you just display the customer no in your edit view (not in a textbox) and use a hidden input to contain the number so it gets posted.
Just a concept type of suggestion. Remove the required validation attribute from your model. In your controller, make the parameter optional and depending on which Action (Edit or Create), you'll manually add in some type of validation.
The jQuery validation can be used to validate from the client based on the input if you go towards the manual route.

use Rails validations to limit to one currently active model

Using Rails 3 validations and/or callbacks, what would be the cleanest way to ensure that only one record of a model has a boolean value ticked as true? I'd like to mark one record as the currently active model.
(I know another option is to use a has-one association, but I'm curious to know how to store this more directly in the model records.)
If all you want to do is validate it you can use
validates_uniqueness_of :boolean_attribute, if: :boolean_attribute
Just drop that in your model class. That will validate that the model has only one boolean_attribute set to true.
Note that you will have to work around the atomicity of swapping the boolean_attribute from one instance to another.
Depending on what database you are using you might be able to resolve it using a transaction. If your database doesn't support transactions you might have to figure out a better way to guarantee data consistency (such us having a dedicated model that points to the "active" model and removing boolean_attribute altogether, or replacing boolean_attribute with an integer that can be atomically incremented (highest number representing the active one).
A callback would probably be the best way. Something like :
before_create :check_boolean
def check_boolean
Model.find_by_boolean_value(true).nil? ? true : false
end
If check_boolean returns false, the create action is cancelled(instead of find_by you can also use exists?, which is probably a bit more clear coding)

What table fields would I need here?

I want to create a commenting model with a twist. I want there to be multiple commenting columns like on hunch.com, except that a user can decide how many columns there should be. Also, a user can decide the title for each column.
This is rather dynamic, so how would I set up my tables for this?
Seems like a perfect use case for NoSQL. I'd use something like CouchDB or Mongo here. Since there you don't have a schema you can add the attributes as needed.
Since you cannot really change the attributes of a model, if you want to create dynamic model attributes, you can have 3 models :
User
Attribute
UserAttribute
Now, you can add as many attributes are you want (Attribute is the static representation of an attribute). Then, a user can have many attributes through user_attributes.

Should I be using callbacks or should I override attributes?

What is the more "rails-like"? If I want to modify a model's property when it's set, should I do this:
def url=(url)
#remove session id
self[:url] = url.split('?s=')[0]
end
or this?
before_save do |record|
#remove session id
record.url = record.url.split('?s=')[0]
end
Is there any benefit for doing it one way or the other? If so, why? If not, which one is generally more common?
Obviously these two have different use-cases.
The first one should be done if you need to access the modified attribute before the record is saved. For example, you want to set the url and at once check the modified value against some condition before saving it to DB.
The second one fits if you only want to do something with the attribute just before saving to the database. So if you access it between the moment of setting and the moment of saving, you'll get the unmodified value.

Resources