I have model 'Human' and this model has integer attribute :age.
For example, I use validation for this integer attribute :age.
When I add new 'Human' with wrong value of :age (e.g. "2aaa3") it is render me back with error, but it is also cut :age like "2". But I don't want it. I want to leave last wrong value "2aaa3".
So, question is "How can I do it?"
That is the default behaviour of validation in Rails. Not sure if there are any other ways to override it. You could however do that validation using javascript, which will be much more user experience oriented than using validates_numericality_of.
Hi everybody who is interested in my question.
I am glad to say I've created solution by myself.
But I have several remarks to that. ))
First, the solution is:
class ApplicationController < ActionController::Base
...
...
after_filter :restore_int_value, :only => [:create, :update]
...
...
private
...
...
def restore_int_value
response.body = response.body.gsub(/(numeric.*<input id=")([^_]*)(_)([^"]*)(.*value=")(\d+)(")/){$1 + $2 + $3 + $4 + $5 + params[$2][$4] + $7}
end
...
...
end
Second, remarks are:
1) the solution works along such gems as 'Formtastic' and 'Simple_form'. These gems build the forms wraped in detailed html and give us possibility to use regex.
If you don't use such gems you can just wrap all your integer attributes, for example, in 'p' tag with 'numeric' class like following and I think my solution will work for this too:
<p class="numeric"> <%= text_field(:human, :age) %> </p>
2) I think my solution will not work for integer fields of nested models in multiple-models-form. (Ryan Bates describes such kind of work in "Handle Multiple Models in One Form" from "Advanced Rails Recipes").
But if you read Ryan Bates' article you will see that he already uses JavaScript. So, working with nested models in form you need JavaScript. Then you can use JavaScript for validation too (as Kunday told). And you will not have a problem. ;)
But if you have static number of nested models in form and do not use JavaScript, then I think you can create new particular regex for your needs (similar to the one I created). I hope you will manage with this. ;)
I hope I've covered all scenarios where you can have such problem and my solution will be useful for somebody, besides me. ;)
Related
I have a code section like the following:
users = User.all(:fname => "Paul")
This of course results in getting all users called "Paul". Now I only need some of the columns available for each user which leads to replacing the above line by something like this:
users = User.all(:name => "Paul", :fields => [:id, :fname, :lname, :email])
Until now everything works as expected. Unfortunately now I want to work with users but as soon as I use something like users.to_json, also the other columns available will be lazy-loaded even due the fact, that I don't need those. What's the correct or at least a good way to end up with users only containing the attributes for each user that I need?
An intermediate object like suggested in How to stop DataMapper from double query when limiting columns/fields? is not a very good option as I have a lot of places where would need to define at least twice which fields I need and also I would loose the speed improvement gained by loading only the needed data from the DB. In addition such an intermediate object also seems to be quite ugly to build when having multiple rows of the DB selected (=> multiple objects in a collection) instead of just one.
If you usually works with the collection using json I suggest overriding the as_json method in your model:
def as_json(options = nil)
# this example ignores the user's options
super({:only => [:fname]}.merge(options || {}))
end
You are able to find more detailed explanation here http://robots.thoughtbot.com/better-serialization-less-as-json
I have the Articles controller and for displaying the respective article I use the basic routes - example.com/articles/4.
I would like to change this URL format to example.com/4-article-name or example.com/article-name-4.
Could anyone give me a tip, how to do that?
Thanks
Ryan Bates(Railscast.com) seems to have done an episode that solves your problem:
/app/models/article.rb
class Article < ActiveRecord::Base
def to_param
"#{id} #{name}".parameterize
end
end
See: http://railscasts.com/episodes/314-pretty-urls-with-friendlyid?view=asciicast
Generally numbers on the beginning is the most elegant way, since in ruby it could be very easily converted to integer, for instance '123-foo-bar'.to_i will return 123.
See http://apidock.com/rails/ActiveRecord/Base/to_param you'll find how to change this mechanism.
I have a rails app that has a list of Products, and therefore I have an index action on my ProductsController that allows me to see a list of them all.
I want to have another view of the products that presents them with a lot more information and in a different format -- what's The Rails Way for doing that?
I figure my main options are:
pass a parameter (products/index.html?other_view=true) and then have an if else block in ProductsController#index that renders a different view as required. That feels a bit messy.
pass a parameter (products/index.html?other_view=true) and then have an if else block in my view (index.html.haml) that renders different html as required. (I already know this is not the right choice.)
Implement a new action on my controller (e.g.: ProductsController#detailed_index) that has it's own view (detailed_index.html.haml). Is that no longer RESTful?
Is one of those preferable, or is there another option I haven't considered?
Thanks!
Another way of doing it would be via a custom format. This is commonly done to provide mobile specific versions of pages, but I don't see why the same idea couldn't be applied here.
Register :detailed as an alias of text/html and then have index.detailed.haml (or .erb) with the extra information. If you need to load extra data for the detailed view you can do so within the respond_to block.
Then visitors to /somecollection/index.detailed should see the detailed view. You can link to it with some_collection_path(:format=>'detailed')
I'm not sure whether this is 'bettrr' than the alternatives but there is a certain logic I think to saying that a detailed view is just an alternative representation of the data, which is what formats are for.
After doing some reading, I think that adding a new RESTful action (option #3 in my question) is the way to go. Details are here: http://guides.rubyonrails.org/routing.html#adding-more-restful-actions
I've updated my routes.rb like this:
resources :products do
get 'detailed', :on => :collection
end
And added a corresponding action to my ProductsController:
def detailed
# full_details is a scope that eager-loads all the associations
respond_with Product.full_details
end
And then of course added a detailed.html.haml view that shows the products in a the detailed way I wanted. I can link to this with detailed_products_path which generates the URL /products/detailed.
After implementing this I'm sure this was the right way to go. As the RoR guides say, if I was doing a lot of custom actions it probably means I should have another controller, but just one extra action like this is easy to implement, is DRY and works well. It feels like The Rails Way. :-)
I have two model Product and Category, they have has_many, and belongs_to association respectively. Now, what I am trying to do is when I click on particular category I want all the products of that category to be listed. How do I do that
here is my view
<p><%=link_to #product.category.name, show_by_category_products_path(#product.category.id)%> <%= #product.name%> <%=#product.category.id%><p>
and method in controller
def show_by_category
#products = Product.where("category_id=?", :id)
end
Thanks! (I know its simple stuff, but sometimes you get blind and can't see a straightforward way so you have to sought help of others)
EDIT
okay maybe I figured out a way to go around this.. but I am not sure if it is done in right way
Now my view and model looks something like this
<p><%=link_to #product.category.name, show_by_category_product_path(id: #product.id)%> <%= #product.name%>
def show_by_category
#prod = Product.find(params[:id])
#products = Product.where('category_id=?', #prod.category_id)
end
Tell me if this is right way?
Your find should look more like Category.find(params[:id]).products. But try to follow RESTful routing principles, and nest your resources. Rails will do much more for you.
I would recommend you to read at least Getting Started guide, because you are doing it wrong.
I'm getting strange output when using the following routing setup:
resources :warranty_types do
resources :decisions
end
resource :warranty_review, :only => [] do
resources :decisions
end
I have many warranty_types but only one warranty_review (thus the singular route declaration). The decisions are polymorphically associated with both. I have just a single decisions controller and a single _form.html.haml partial to render the form for a decision.
This is the view code:
= simple_form_for #decision, :url => [#decision_tree_owner, #decision.becomes(Decision)] do |form|
The warranty_type url looks like this (for a new decision):
/warranty_types/2/decisions
whereas the warranty_review url looks like this:
/admin/warranty_review/decisions.1
I think because the warranty_review id has no where to go, it's just getting appended to the end as an extension.
Can someone explain what's going on here and how I might be able to fix it?
I can work around it by trying to detect for a warranty_review class and substituting #decision_tree_owner with :warranty_review and this generates the correct url, but this is messy. I would have thought that the routing would be smart enough to realise that warranty_review is a singular resource and thus discard the id from the URL.
This is Rails 3 by the way :)
Apparently it's a long standing rails bug where polymorphic_url has no way of knowing whether a resource is singular or not from the routes setup:
https://rails.lighthouseapp.com/projects/8994/tickets/4077-wrong-redirect-after-creation-of-nested-singleton-resource-using-responder
I'm just going to resort to using a non-singular route even though there will only ever be one warranty_review. It's just aesthetics at the end of the day.