I have a model with a column called start and typed as :datetime.
I would like to be able to calculate how many days there are until the start date and time.
Currently, I have a simple view that does
<%= #myModel.start - Time.now %>
This gives me something like -650.878217378
How can I get it to display days and hours until that date
It seems wrong to be doing this in the view - should I make another instance variable for this calc in my view?
Thanks!
The distance_of_time_in_words / distance_of_time_in_words_to_now view helpers will produce human friendly strings, see the rails docs for examples.
If you are going to be doing calculations like this and the rails provided view helpers don;t meet your needs, I'd write my own view helpers. I don't think there's anything 'naughty' about doing
<%= distance_of_time_in_words_to_now(#myModel.start) %>
Related
I'm junior RoR programmer.
I know that Ruby language has a calculate method, When I type this in rails console: ModelName.average(:something),it calculates the average value from field :something. It works, but how to add average value to the view?
I have a Items catalogue. Every item has a Review which include rating (integer).
How to display on the view (i.e. show.html.erb) the average value from all rating fields in Review model?
There are multiple ways of doing this. Easiest way is exposing it as a state on the controller, which is the #average, which can then be accessed in the view. As easy as it might be, I don't recommend this approach.
What I do recommend is, adding a method on your model,
model_instance#review_ average and when you are exposing (using the #model_instance) the instance of the model in the #show action of your controller to the view, you can just call #model_instance.review_average
What is the advantage of the second approach? It hides the logic from the view and controller, and pushes it into the model, which in turn makes it easier to write an automated test case.
for implementing average, check: How do I create an average from a Ruby array?
I'm also guessing that you have a has-many relation. It should not be too difficult to do the above.
One thing that you have to also keep an eye for, is n+1 queries, But this becomes an issue only when you have to show the avg in the index page.
Simply add the following to your show.html.erb :
<%= #model.average_rating %>
RESOLVE STEP BY STEP:
first step: Add to your model controller, to def show:
#rating = Model.where(:model_id => params[:id]).average(:attribute).to_i
second step: add to your model view to show.html.erb:
<%= #rating %>
model_id = your model, i.e. Post will be :post_id
:attribute = your attribute, i.e. :rating
It's all.
I have a system which handles reservations. I am writing the UI for a user to select a start and end date which is submitted to the rooms controller and returns all available rooms for those dates. I'm struggling with
The actual form
Processing the dates in the rooms controller.
Having used form_for a lot, I know how datetime_select works, but using form_tag I can't seem to find how to implement the same thing.
Also, it looks as though using datetime_select :year, :start_year passes the date to the controller in 5 parameters, which is going to be messy to parse.
I wonder if I configure the form properly, the controller will know how to parse the date natively and automatically solve the second problem
Thanks for your help!
Check out this answer if I understand your question correctly then you can implement it in the same way as you would using form_for.
I have a rails 3 app where users select an option from a select input which is stored as an integer. The select input is populated by a :collection with simple_form gem, for a table that I seed. This is working exactly the way that I want.
However, I want to display the name instead of the integer in my views.
Right now I am doing this in the view, which is obviously not a best practice.
<% mfg_num = #product.manufacturer.name %>
<%= "#{ListOfManufacturers.find(mfg_num).name}" %>
So, my question is:
What is the best practice for setting up something so that I don't need to put this logic in my view? Should it be in the controller? Should in be in the model? And how do I do it?
there're couple of solutions to this problem, these are:
use instance variable in your controller and use it in the view, smth like
............
#product.manufacturer
#man_name = ListOfManufacturers.find_by_name(#product)
............
use helper method or method in your model
these're good practice
I'm working in Rails3 and I would like to render a partial depending on a specific date/time. For example, on Christmas I want to show the Christmas content, on Halloween the Halloween content, etc. It would be great if the partials were stored in a datastore somewhere and called out depending on some metadata.
I can do this in a one-by-one type of way but I wanted to know if anyone knew of a Gem that may already do something like this. I'm fairly certain that I'm not the first person to want to render code depending on a date/time. However, if there are no ready made solutions, do you have any clues as to how to architect a mechanism to allow "content-owners" to maintain these partials without programmer involvement?
I would have a table with a 'date_start' and 'content' fields.
In the controller, I would select the first record where 'start_date' is less than or equal to the current date and then render that content. See the code below (untested, but you should get the gist).
in controller:
#record = Table.where('start_date <= curdate()'.order('start_date desc').limit(1)
in view
<%= RedCloth.new(#record.content).to_html.html_safe %>
That should get you started, let me know if you need more information. Once you refactor, you could put the code from the controller in a model and use scopes.
I'm trying to use attr_accessor for a date which normally works fine except when I attempt to use it with the select_date helper method.
Looking at the code behind the helper method I'm guessing it looks for the table column with date type. And in this case since there is no table it's not handling it correctly and I get:
ActiveRecord::MultiparameterAssignmentErrors
"search"=>{"number_of_days"=>"3",
"searchable_id"=>"6933",
"startdate(1i)"=>"2011",
"startdate(2i)"=>"2",
"startdate(3i)"=>"11"}}
Is there a way around this? Or do I need to create some kind of before filter in the controller? I'd prefer doing it on the model level, but I'm not sure how to handle this case? An attr_accessor for each seems a bit over kill. Anyone else have an elegant solution?
attr_accessor fields don't usually get saved when you save/update to the model. How are you updating the model?
Also, you can convert the startdate params to a date object like this :
#start_date = Date.civil(params[:search][:"startdate(1i)"].to_i,params[:search][:"startdate(2i)"].to_i,params[:search][:"startdate(3i)"].to_i)
Check here
select_date is for building the dropdowns which are not associated with a model field (with the idea that you can then pick them up on the other side and do what you want with them). I assume you're meaning date_select which does run off the model?
In any case, as far as I know, long story short, there's no nice and pretty way to get this to work. It's not because of the way the helper works, but because of the way that active record deals with these attributes split into multiple parameters.
In a bit more detail if you're interested, the reason why this doesn't work easily is because when Active Record is dealing with the params you've passed in, it goes through execute_callstack_for_multiparameter_attributes which interprets the keys which have been split into the "date(1i)" style, and mungs them into the applicable class which they should be (a date or time object). The way it works out whether it should create a date or time is by checking it against the type of the attribute (see here), but since an your 'startdate' attribute isn't bound to a particular type, it doesn't get treated as a date or datetime column in the db would.
I think I would deal with it similarly to #Phyo-Wai-Win, but use select_date to set a different param, outside of the 'search' namespace which you then pass into the model as appropriate in the controller. This way, it's not much work, and it means you're not messing with the way you initialize the record or what attributes it expects.
Coming in way late, but in case anyone else stumbles by, the answer for modern rails lies in include ActiveRecord::AttributeAssignment in your model.
This answer did it for me.
I'm a little late here, but I just came across this problem and did not like the top answer. I found a method in the ActiveRecord source called extract_callstack_for_multiparameter_attributes (this is different than the method idlefingers mentioned)
I have the following method in my model. I am calling this method manually but you could probably override update_attributes to run it automatically when you save from the controller. The params argument is actually params[:my_model] from the controller.
attr_accessor :submit_from, :submit_to
def set_dates(params)
dates = extract_callstack_for_multiparameter_attributes(params)
dates.each_pair do |field, date_array|
send "#{field}=", Date.new(*date_array)
end
end