Is there a good way to debug ? I now actually look at the console output from console/server. I also see <%= debug(@order) %> from the book, which I haven't tried. But the debugging process for me seems to be very slow.
My particular scenario: I am trying to create a measurement. The controller code has something like: @measurement.name = params[:name] (which is similar to some code in CCC, but didn't work for me)
I looked at the console output of the server, it has:
I changed the code to: @measurement.name = params[:measurement][:name]
and this worked. But this doesn't feel right. Am I doing something wrong ?
Thanks
jgn
· 1 year ago
You could do it that way.
You probably preceded that code with: @measurement = Measurement.new
Your code is saying:
-- Copy the value associated with the :name key in the hash under the key :measurement in the params hash to the "name" attribute of the @measurement instance variable.
BUT, the whole point of Rails's automatic handling of the params hash is that you should be able to say . . .
But notice: params[:measurement] itself is EXACTLY suitable for the what is passed to .new!! It has a key called :name with the appropriate value! So this is virtually equivalent:
Note that this is covered in the required reading, in the the video of the lecture, and in the PDF of the slides, which are on the downloads page. If you study the assigned material, you will find, for instance, on Slide 54 of the PDF, or slide 73 of Hour 2 of the video for Lecture 9, a "canonical" example of how to implement the "create" method for a standard CRUD controller.
I make the point about the params hash on slide 36 during Hour 2. I really belabored the params hash and its magic through several slides -- I was quite worried about boring everyone, but I guess I was right to spend some time on it. PLEASE review the lecture. If there is anything I can do to make this more clear, please let me know, but this is super super super basic stuff.
In the book you want to take a look at figure 22.1 -- as you will recall, I added this very diagram to a slide and said how important it is. That diagram and the following page discuss EXACTLY what you are concerned about.
student1
· 1 year ago
Okay John, thanks. I will only learn it when I do it.
jgn
· 1 year ago
That is true, but keep Fig. 22.1 at your side. You are doing the right thing to keep looking from your code to the log to the book, etc.
student1
· 1 year ago
In addition, now, I have the following in my server console when I edit the Measurement.
Parameters: {"action"=>"edit", "id"=>"1", "controller"=>"measurements"} Measurement Load (0.000191) SELECT * FROM "measurements" WHERE ("measurements"."id" = 1)
This comes from
@measurement = Measurement.find(params[:id])
This is something done in CCC. But it seems like the SQL has measurements.id rather than id ? I am not sure what is happening. (I also always get confused by the singular and plural)
Could you explain ?
Thanks
jgn
· 1 year ago
Good question.
Recall:
Model name: Singular. Why? Because each instance of Measurement represents one measurement.
Table name: Plural. Why? Because the table contains many rows, each of which describes a single measurement. Thus the plural for the table name (measurements).
So . . . If you are manipulating an instance of Measurement, and look at the log which is showing the SQL to the database, you will see the table names . . . which are plural (if you follow the Rails conventions).
student1
· 1 year ago
I am having quite a bit of problem with controllers. The MeasurementController seems to be okay. i.e. I seem to be create update delete measurements. However, the ObservationKindController seems to be giving me a lot of problem. (1) I seem to be able to create quite a few new observation kind in a row. When I click on "Kind of Metric" again, I sometimes see them all. But, sometimes, rows seems to be automatically deleted. I am not quite sure how to debug this.
(2) I also tried destroy. I know that my items is destroyed. I do send it to the index page after it is done. But looking at the access to the database from the console log, not only do I see the select * from observation_kinds (from the index page - listing the metrics kind), I also subsequently see a select for a particular observation_kind by an id that correspond to the item that has just been deleted.
So, it has been quite confusing.
The code for Observation kind is essentially a copy of the Measurement (except for the deletion). So, I am not sure what is going on. Could one error in the destroy mess up all the subsequent operations. I actually ^C the server and restarted. But that doesn't seem to help.
The way I do destroy is: @observation_kind = ObservationKind.find(params[:id]) @observation.destroy Then I redirect to index (whether it is successful of not)
Is there a good way to debug ? Thanks
student1
· 1 year ago
In fact the rows seems to disappear even though I did not ever press the destroy link
student1
· 1 year ago
I think I find a situation that results in such confused behaviour. I use vi to edit files. So after editing index.html.erb, I will in addition has index.htmt.erb~ I thought they were innocuous and don't bother to remove them. After removing all these *~ file in the controller and the view/* directory, the strange behaviour disappared.
I don't know if this really is the reason why Ruby gets confused. But it seems to work now.
philadelphia
· 1 year ago
Hi,
On the http://metricsmine.plugh.org/observation_kinds site, if I add a Metric Kind and then go to delete it, it generates an error. It says "The page you were looking for doesn't exist".
Mike C
jgn
· 1 year ago
Thanks.
When I was preparing the app so that various actions and views are stubbed out, I removed the "list" action in some controllers in favor of always using "index".
So . . . this is a bug.
I just fixed it.
It shoudn't affect your assignment because the "destroy" action isn't implemented in the ZIP (you implement that action).
a href="/observation_kinds/destroy/2?method=post">(destroy)
I guess my question is, should I be worried about the creation of the javascript snippet you have online? If so, can you point to a way to auto-create this from some Rails macro?
Thanks, Mike C
jgn
· 1 year ago
That JavaScript will be generated automagically for you by Rails if you use the correct view helper . . . .
Here is what it is doing:
-- Remember that HTTP can do a number of methods, the most common of which are GET and POST (there's also DELETE, etc.)
-- In the default case, link_to will do a GET.
-- But is a GET suitable when you want to delete something? No, it isn't. Why? If, after the GET, we did not redirect, we might bookmark the GET, and/or refresh the page, and attempt the GET again -- and thus to to the :destroy action again. This is not right.
-- What we want is a POST. link_to allows an option :method => :post
-- So, on-the-fly, Rails creates a little form so that when you click the "delete" link, you actually POST back to the server. POST is for making changes in server data.
By this means, Rails uses the appropriate HTTP method for the operation.
If you turn off JavaScript, it will use a GET (which will work, but with the dangers described above).
One of the benefits of doing it this way is that your site can more properly leverage the HTTP methods. We will talk some about this Wed. night when I go over REST.
In LinkWizz, you should see the same thing for the research_topics list. I don't think we do any deletions elsewhere.
Notice the curly braces in the second one... this is what generates the javascript output.
Mike
jgn
· 1 year ago
OK -- That's misplaced in LinkWizz. What you see in MetricsMine is correct. I'll double-check it when I get home.
philadelphia
· 1 year ago
John,
I should have said... It's absolutely correct in LinkWizz. It's my user error that caused the issue. I simply did not add the curly braces. When I typed the line it, I missed them. I should have cut and pasted.... Anyway, hopefully this might help someone else.
Mike
jgn
· 1 year ago
OK.
What this is about:
There are actually two hashes at the end of link_to
The first Hash: This is for URL generation (:controller =>, :action => etc.).
The second Hash: HTML options (:method =>, :class =>, style => etc.)
Keith
· 1 year ago
'Rails is really finicky about braces' -- this is not really the case. John notes above that there are two hashes at the end of link_to -- more accurately, if you look at the API docs for link_to (http://api.rubyonrails.org/classes/ActionView/H...), it accepts three arguments, two of which are hashes. Now that we're using Rails, it is important to reference the docs on issues like this -- e.g. whether or not you have the method signature correct.
I think this is an area where the docs are confusing -- note the number of different styles they use. Which hash does :method belong to? It depends on which form of link_to you are using.
philadelphia
· 1 year ago
Right... I should have said that at times Rails has a very confusing syntax and does not necessarily provide any error or warning when a method is invoked with a potentially incorrect set of parameters. And further that simple mistakes are compounded by the lack of feedback provided by the framework.
jgn
· 1 year ago
Well, that's why we provide complete working (well, sometimes) code examples, so that you can move between your attempts and some code that allegedly works . . .
philadelphia
· 1 year ago
:-)... learning a lot... That's what I'm here for. There are many ways to do things in Rails, and the syntax allows for a ton of variations... There are a ton of conventions as well, and reading about them is like reading the encyclopedia... Practice is the best way I know of to learn it. I keep working on it every day. It's clicking but not as quickly as I am used to...
Mike
DanielS
· 1 year ago
So I have to say that I am still confused by the documentation on this (though I have things working). In order to get the javascript to come out while I still used the curly braces in the call to link_to I had to use the following syntax:
Now according to the docs the following is the method signature for link_to:
link_to(name, options = {}, html_options = nil)
This would indicate that :method is one of the html_options. Yet under the 'Options' heading it lists 4 options:
:confirm :popup :method html_options
This would indicate that it is one of the options. This is all very confusing.
jgn
· 1 year ago
You've done it right. Incidentally, could you paste in the URL to the documentation to which you are referring?
Also:
I think Morris pointed this out: In lecture or possibly a comment here, I suggested that the :method => :post was on the first options hash, not the html_options hash, and possibly that the JavaScript is created as a result of something in the first options hash. But it is in fact the :method => :post in the 2nd hash that triggers the fancy JavaScript.
What they are giving under "Options" -- namely, options with keys such as :confirm, :popup, and, crucially, :method, are all for the 2nd (html_options) Hash.
For the first Hash, you are supposed to look at the options for url_for.
But there is no indicator I can see that the options for link_for are specifically for that second (html_options) Hash.
For what it's worth, the discussion in AWDR is quite clear. In the latest PDF, that's on page 495. On p. 496 :method is discussed, and how it works to force a POST even though it's a link.
student1
· 1 year ago
I have 2 questions:
(1) Is the UTC in your timestamp on your metricmine page printed by some specific time helper method. I didn't find a particular simple method that prints out the time stamp the way you have it on our web pages. I use for to_formatted_s (which does not have UTC, and it is not in UTC) time. There were suggestions of strfttime...but they also, isn't exactly like yours ?
(2) My button looks different from yours. You have a blue button, and it is retangular. Mine has round edges. Is there a css style sheet we should use. I already have one public/stylesheets/layout.css
Thanks
jgn
· 1 year ago
(1) Where are you seeing UTC in the UI in a part you are supposed to implement?
(2) Do not change the layout; do not change the CSS. The basic page layout comes from views/layouts/application.html.erb, and that loads CSS from public/stylesheets - it should look roughly the same. If you like, e-mail me a screenshot.
ALSO, are you basing your new work on the latest download?
Morris
· 1 year ago
The "UTC" shows up, for example, in the "Observation Kinds" table, for the "created at" date/time.
jgn
· 1 year ago
Thanks.
Yes -- Just using the default output there. I wanted to make sure we were talking about a specific display.
Elsewhere, it can be convenient to use the strftime method on a datetime object, e.g., something.created_at.strftime('%d-%b-%y')
Incidentally, the standard practice is to store datetimes in UTC in the database. Then tailor it for the user, according to their wishes. Here's an interesting blog post on how to do it for Rails 2.1 -- we are thinking about making time zone support an option for the final project:
You should already have the correct stylesheets included, if you're starting with the contents of the downloaded zip file. All of the necessary stylesheets are in the public/stylesheets directory, and the default application layout file links to those stylesheets. In the supplied material as I've downloaded it, the stylesheets directory contains 8 stylesheets, and the application layout in the layouts directory references 7 of them.
If you "view source" with your browser on any page that has a button, for example the users/login page, you can see the HTML for the rectangular blue button, and the corresponding .html.erb file for that view will show you the Rails code that generates that HTML.
Morris
· 1 year ago
Re: the "UTC". It looks like if you just print out the value of a 'created_at' field, it comes out just right: the default format for ActiveSupport::TimeWithZone#to_s appears to be exactly what we want.
philadelphia
· 1 year ago
Hi,
I have a question about the preferred_unit... I'm not sure of the purpose for it... the data model calls for unit_id. The migrations use it in establishing the relationship between observation_sets and units. But where is it supposed to be stored? How is it accessed? And for what purpose?
Mike
jgn
· 1 year ago
I will try and write the following up at greater length this evening.
The idea is that an observation can be made with a different unit.
Say I'm in England. I weigh myself on a scale, and get my weight in kg or stone. I would like to be able to add that observation. At present we don't allow this in the UI.
Obviously, if the observation set has one unit, and an observation (in that set) has a different unit, it is important that both units have the same measurement (e.g., weight - you wouldn't want to have an observation_set with a unit in, say, feet, and an observation in pounds, 'cos those are two different measurements, length and weight, and thus aren't comparable). This isn't enforced now. Sometimes the schema is a bit in advance of the product.
Now, why the preferred unit: The idea is that the observation_set has a "recommendation" for the unit for all observations that are made under that observation_set.
The upshot of this is:
(1) When an observation set is created, set the preferred unit to the first unit available for the measurement of the observation kind from which the observation set is being created.
(2) When an observation is created, use the unit from the observation set.
I think there might be a gap in the implementation where the unit_id is not being set right when an observation is created -- I'll double check that, too.
philadelphia
· 1 year ago
John,
Thank you.
But shouldn't there be a preferred_unit column in the observation_sets table? (There isn't one).
That is, "(1) When an observation set is created, set the preferred unit to the first unit available for the measurement of the observation kind from which the observation set is being created."
I'm definitely doing this... and I am saving the record.... then I'm redirecting to the index page... and it starts to create the page, but dies because it can not find form.preferred_unit.name...
So it goes...
Mike
jgn
· 1 year ago
There is such a column, but it is called unit_id. The association is called preferred_unit:
My error was being caused by a data mismatch in the tables. I had gotten things a tad out of sync while developing... So, there had been no matching rec in the units table to be found from observation_sets. Hence, it was causing a nil error. That part is working now.
I'm a bit confused still on the association name... I see that I can use the name to access the data in the remote table. But, I do not see what code is being executed to get there. I had expected to find some generated code (somewhere) based upon the "belongs_to" in the model. But there wasn't any (that I could find)... I could see the preferred_unit as a method from observation_sets... Where is this method defined?
Mike
jgn
· 1 year ago
When you declare that association "preferred_unit" method missing catches such method calls and hands it over to ActiveRecord so that it can find the right related rows from the database . . .
Arguably, the association does not need to be called "preferred_unit" but we did that for the assignment to . . . make it a bit more challenging. It's the only case in MetricsMine where the association name isn't conventional. Hence, the use of :class_name and :foreign_key
Morris
· 1 year ago
"Notice the fancy JavaScript for the “(delete)” link. The view helper link_to’s :action => ‘destroy’ option will do all of this for you."
Actually, it appears that it's :method option that does this, not the :action. See pp. 495-496 in AWDR, and notice that :method is an HTML option (not at all clear in the Rdoc).
jgn
· 1 year ago
Correct - my bad.
Morris
· 1 year ago
The FAQ says we can't change the HTML. Does that mean we have to replicate non-functional HTML, such as the empty <div> elements that are in some of the forms?
jgn
· 1 year ago
Actually I was thinking specifically about the HTML and CSS in the code we give you, and, very generally, the HTML that you implement.
Basically I want what we give you to stay the same, so that when we're grading, we're not bewildered by a strange-looking interface. On occasion a student creates a new stylesheet or goes way overboard in streamlining the interface. But that's not what this course is about, so it is wasted effort, and possibly something that jeopardizes our ability to grade.
You should be able to skip extraneous markup (such as empty <div>'s) in what you implement. It may be, however, that it is doing some structuring that isn't immediately apparent.
Incidentally, the teaching staff uses Firefox, so if it looks ok in FF, I think you're ok -- no need to check with Internet Explorer, Opera, or other browser.
Manuel Ledesma
· 1 year ago
Deleting, I don't know if I'm assuming the the right behavior but for measurement and others, I'm checking that no children are associate before deleting them. I don't know if should do it this way or simple destroy it.
Here is an example for Measurement
id = params[:id] units = Unit.find(:all, :conditions => ["measurement_id = :id", {:id => id}]) observation_kinds = ObservationKind.find(:all, :conditions => ["measurement_id = :id", {:id => id}]) @measurement = Measurement.find(params[:id]) if units.size == 0 && observation_kinds.size == 0 if @measurement.destroy flash[:notice] = 'Your measurement was successfully deleted.' else flash[:error] = 'Failed to delete measurement.' end else flash[:notice] = "Measure #{@measurement.name} cannot be deleted, You must delete all Units and/or Observation kinds that reference it first." end
jgn
· 1 year ago
Manuel,
If you will look at the reference implementation -- or at the static HTML -- you will see that we don't provide a means to delete a measurement. This is deliberate, because if you deleted one, it would cause havoc with existing observations.
This was a design choice. To be sure, your strategy would be a decent way to prevent such havoc and allow the deletion of a Measurement . . .
BUT, we do not want you to implement more than the requirements!
Please, do not implement extra functionality. Do a great job on what is required.
John
student1
· 1 year ago
Hi John,
Looks like my strange deletion problem is back. I really do see (something/someone) automatically deleting my observation_kind. While I was adding in a few measurement_kind (without deletion), one of them magically got deleted..
I have a snippet of the log when this happend. Would you be able to look at that. I have sent it to my TA as well. But in case you get a chance to look at it sooner, then I could proceed with the other part of the assignment.
I also noticed that in my log, there seems to be 2 sessionIDs:
Either there are 2 sessions going on without me noticing (I only run 1 session at a time), or this is normal. I use only 1 tab in the same browser as far as I know.
In any case, I didn't do any deletion during the session, and a row just disappeared.
Do you have any suggestion on where to look ? This problem has been going on, but it was intermitten.
jgn
· 1 year ago
Those session id's like identical to me.
One thing that could be happening is that somewhere you are redirecting to the wrong page -- or, possibly, you are calling a method in your controller twice.
Why don't you go on to the other parts of the assignment anyway? I don't think you should let this hold you up.
student1
· 1 year ago
okay, John. I will move on. I've spent too much time on this already. I will just comment out the destroy code.
The Session ID are not the same. One has 3 lines, the other 4. The 3rd line is different. I am not sure why one has a much longer ID.
I redirected to the correct page. The TA has seen that code at the time the problem appeared the first time. And this time, I didn't even do a deletion while adding in more observation_kind. But this IS strange.
jgn
· 1 year ago
The session id in the log starts with the session id -- the extra stuff (e.g., "CkB1c2VkewY7CUY=--b6c94f16882989fe21d2a65e2858309809d2bab9") is an encoding of what is actually stored in your session. I am not 100% sure where the session id ends and the new data begins, but that is the way sessions work for the cookie store.
So: I don't think this has anything to do with your sessions.
Review your code for adding a measurement. Are you accidentally calling a method to delete a measurement?
I understand why you say, for instance, that you "redirected to the correct page." However, you have a bug, so it is futile to claim that your code is correct. You need to keep looking at it.
Note that if you created a user, but the database was reset, the code that handles the cookie creates an error.
I will fix that tonight -- it's a bug.
In the meantime, remove your cookies for the metricsmine.plugh.org site -- in Firefox:
Preferences / Privacy / Show Cookies / search for metricsmine
Then delete any cookies you see.
Morris
· 1 year ago
The assignment says, "We don’t want to see “raw” HTML links, form actions, etc., etc.". But how far should one take this? You could write your entire view without any HTML at all, just using the "content_tag", "content_tag_for" and "tag" helpers when there's no specific helper for an HTML tag, but this would be much less readable for someone who just wanted to get a high-level idea of the HTML. E.g.
The observed_at field according to the reference DB, it should contains the date and all time field values should be 0, But according to the implementation reference we should allow user to enter hour, time and second. I can only get it by setting the :include_blank => true and not touching the those fields. Also another problem is that once Datetime is create, they are immutable. we can fix it by using both :include_blank => true and :discard_hour => true but it won't follow the implementation reference. Any hint?
jgn
· 1 year ago
Manuel,
Do you mean the reference DB used for checking whether or not your migrations and associations were good? You should not be using that as a guide for how values should be set up in the database.
Users do need to be able to enter an observation for any time -- are you having trouble with the form.datetime_select helper?
John
Manuel Ledesma
· 1 year ago
Meaning that we don't need to expose the hour, time, seconds from the form.datetime_select field, right?
jgn
· 1 year ago
You should.
I'm not sure about the question -- in the reference implementation and in the static version of the page, the hour, time, and seconds are there as drop-downs, right?
Am I missing something?
Manuel Ledesma
· 1 year ago
Sorry, I found my issue.
Manuel Ledesma
· 1 year ago
Since ObservationKind can be deleted, Do we just display a [Not Observation Kind is assigned] instead of the name? or what else?
Manuel Ledesma
· 1 year ago
Since ObservationKind can be deleted and the observation_kind_id will be set to null to any observation_sets assoicate with it, Do we just display a [Not Observation Kind is assigned] instead of the name when go the action show? or what else?
Same situation will apply when trying to create a new Metrics, should we raise an exception or display a message say that you need to define observation kinds first. http://metricsmine.plugh.org implementation seems no to handle this situation.
jgn
· 1 year ago
Good point.
Note that the only person who can delete an Observation Kind is an admin. Presumably the admin knows that if all observation kinds are deleted, then the application would fail in this regard. So . . . we will consider this a bug rather than a feature, on the assumption that the admins would not willy-nilly delete Measurement Kinds.
Admins, do not delete all of your Measurement Kinds!
Manuel Ledesma
· 1 year ago
Thanks for the clarification. I just added some code to handle the situation at least for show.
jgn
· 1 year ago
Did you check the static view I prepared for you!? Here's what it says:
<%# Next line should show metric kind dynamically; if # it's null, show nothing. %> Metric kind: personal weight
You can verify the behavior with the reference implementation.
Is the comment clear? This is from views/observation_sets/show.html.erb
Manuel Ledesma
· 1 year ago
Thanks !!!, Now I'm clear.
student1
· 1 year ago
I seem to recall that it was mentioned in class that there was a way to check that an input field in the form is a number. But after searching lecture 8, 9, 10 several times and and api.rubyonrails.com, I fail to find this. I was looking under text_field.
If we really could do so, could you point me to the information. Thanks.
jgn
· 1 year ago
It's a validation. Like all validations, it does not happen in the view markup (that is, not in text_field or any of the other helps).
Validations are declared on the model. I explained how these validations worked a few lectures ago.
If you will take a look at the Observation model in the latest download, you will see that the following has already been declared for you:
validates_numericality_of :amount
If you want to display the results of that validation, you will need to use the error display helpers -- for examples of that, see CCC or LinkWizz, or the lecture slides.
student1
· 1 year ago
Thanks.
student1
· 1 year ago
Regarding the hidden field, I am a bit confused: (1) The form itself does not have anywhere one could change the observation_set_id to begin with. So, I don't know how the user can change this. (2) So far, I have been embedding them in a instance variable. Is that okay ? The way I get to adding an observation is by clicking on an observation set, in the list of observation sets. So, as a result, I get into the controller knowing the observation_set_id. At that point, I can set an instance variable which passes to the view. The view will go back to the controller by setting a parameter using that above instance variable.
Does this not work ? Or should we set the instance variable instead.
I have a different questions. The time in creating observation - there are broken up into 6 fields. Each of the time related field does not by itself correspond to an attribute for the observation. So, I simply create a different hash altogether. Does that sound reasonable ? I use "select" to generate the options for hour/min/sec/year/day. But I don't see a month_selection helper. I wound up using html. Is this expected ? This seems to work, but I have a feeling that the month_selection is often used, so there may be some method I am missing. Am I doing it right ?
Keith
· 1 year ago
I don't know which form you are referring to re: using a hidden field, but I don't see why you'd need to use one when creating an ObservationSet. You probably need one when dealing with an Observation.
Look at date_select and datetime_select; there is no need to generate html. Rails will convert the data passed in from those selectors into data that is compatible with the database.
student1
· 1 year ago
I still don't see why I would need one in creating an observation. The hidden field is to store the observation_set_id. However, I put that in an instance variable. THe way I get to the observation creation is by clicking from an observation set list, so I don't see where I would need one.
Keith
· 1 year ago
The instance variable doesn't persist to the next request. When you click on 'Add', you won't have access to @observation_set_id any longer.
student1
· 1 year ago
But I did this { :action => :create_observation, :id => @observation_set.id }
So, some comes in the view as an @observaion_set The view does what it needs to do, but, with :id => @observation_set.id, the params[id] is now set to what comes into this view as @obervsationse
So, in summary, a <value> comes into the view as an instance variable The value is placed into :id => <value> and send to the controller. The controller then reads the <value> from params[:id]
Is this not okay ?
Thanks,
jgn
· 1 year ago
When you create an OBSERVATION, should its (the observation's) ID (the unique id that identifies a particular observation) be set to the id of its observation set?
No. The observation_set_id on the observation should be set to the observation_set.id. There are two id's in play, one for an observation, the other for an observation set.
When you display a form to create an observation, do you know the id that the database will give a new observation when the form is displayed? No, you don't. The id should not be specified at all for the :create action, because when the create action takes over, it will get the new id from the database.
Would you e-mail me privately? john at 7fff dot com
Morris
· 1 year ago
For selecting a time in a form, there are helpers for this in the ActionView::Helpers::DateHelper class. http://api.rubyonrails.com/classes/ActionView/H... I thought I had seen an example of this somewhere in John's sample code, but I can't find it now. I'm fairly sure AWDR gives some examples.
You could pass the observation set id as a parameter in the URL for the form, but my personal interpretation of the requirement not to change the HTML is that we're supposed to use the hidden field in the form, which will make all of the information stay in the POST parameters. There are helper methods for hidden fields.
jgn
· 1 year ago
I see that there are some answers already to some of these questions, but here are some brief confirmations of what is below:
-- When an observation is added, it must be added TO an observation set. Therefore, when the form that lets you add an observation posts back, there must be some indication of the observation set id to which that observation should be added. Therefore: (a) you may pass the observation_set_id to the form in an instance variable; (b) use a hidden field to capture that id so that it is sent back when the form is posted; (c) in the action to which the form posts, obtain the observation_set_id from the params hash.
-- For time forms in forms: Take a look at the ChildCare Co-Op application. The helper is: datetime_select - it has many options.
student1
· 1 year ago
So does that mean that we don't have to necessarily do the hidden variable (b), since I was using the instance variable method (a)
Thanks
jgn
· 1 year ago
I don't see how that would work.
Think about it this way:
-- You set an instance variable. -- A form is displayed. -- The user clicks "submit" or "add observaiton" (whatever's on the button). -- Now a new controller receives the request (i.e., the "post" of the form)
How does this new controller know what observation_set_id you want?
You have to get that observation_set_id into the params hash.
And how do you do that? Include the observation_set_id in a hidden field.
Morris
· 1 year ago
But:
I haven't experimented with this yet (I'm in the middle of creating a rudimentary two-model Rails app to test it, but my son wants time on the computer before he goes to bed), but if I'm reading the Rails documentation correctly (an iffy proposition at best), then we might be getting the observation set id for free in params[:id] -- the documentation for the options for "form_for" says something about the options being the same as for "url_for" and "link_to", and the doc for ActionController::Base#url_for (http://api.rubyonrails.com/classes/ActionContro...) says,
>>> When generating a new URL, missing values may be filled in from the current request‘s parameters. For example, >>> url_for :action => ‘some_action‘ will retain the current controller, as expected. This behavior extends to other parameters, >>> including :controller, :id, and any other parameters that are placed into a Route‘s path. Â The URL helpers such as url_for have a >>> limited form of memory: when generating a new URL, they can look for missing values in the current request‘s parameters. >>> Routes attempts to guess when a value should and should not be taken from the defaults.
It's probably better to include the id explicitly when it's desired, both to show the reader of your code that the id is wanted, and to make sure you really get what you want, but it seems as if it's not 100% necessary.
jgn
· 1 year ago
When you create an observation, the form is "for" an observation.
So the data will be posted into params[:observation]
If the id on the URL (i.e., the id for the observation_set) was used for params[:observation][:id] that would clearly be wrong.
Morris
· 1 year ago
I was thinking that the id from the previous request would end up simply as params[:id] for the next action. Now that I've tested this out, I see that this isn't the case, but I don't really understand it, just from reading api.rubyonrails.com.
However, seeing what does come in the params, I see that having the observation_set_id as a hidden value in the observation form handily puts it in exactly the right place, so that params[:observation] contains exactly what it needs to get passed as the argument to Observation.new.
jgn
· 1 year ago
I'm a bit surpirsed that the id from the previous request isn't set up as params[:id] -- I will try to get to the bottom of that tomorrow.
In any case . . . as you say: "having the observation_set_id as a hidden value in the observation form handily puts it in exactly the right place, so that params[:observation] contains exactly what it needs to get passed as the argument to Observation.new" -- Yes, ahem, that's exactly what I tried to spell out!
Morris
· 1 year ago
Following up rather late, here: the reason the id from the previous request isn't getting used is that the new URL has a different action from that request. The Rdoc does explain this, a bit cryptically, in bits that I didn't quote above, referring to a hierarchy. So if you specify a different controller, then neither the action nor the id gets copied into the new URL, and if you specify a different action, the old id gets dropped. This is addressed somewhat more clearly on pages 415-417 of AWDR. If we really wanted to use keep the id in the URL in this case, instead of (or in addition to) putting it in a hidden form variable, we can either include it explicitly, or use :overwrite_params to change the :action while retaining the following parameters
jgn
· 1 year ago
Very good -- great sleuthing. I suppose I would say that there's a pedagogical advantage for the hidden field for web app programming generally, but I'm missing out helping people do it in a more Rails-esque way!
Morris
· 1 year ago
In this case, I think the hidden field is Rails-esque, because it greatly simplifies the code for the action, by putting everything into the hash that gets passed to new().
student1
· 1 year ago
I think what happens is that I get to the create observation page from the page that list observation set. When I click on one of the observation sets on the list (the "RAW"), this brings me to the observation_set controller, with an ID parameter for the set. From this, I can set an instance variable, before going to a view that allows me to add observation for that set. Hence, I have the obseravation_set_id. (It seems to be working ????)
Suppose you just can arbitarily jump to a page that add observation, without going through the observation_set page, then, you wouldn't have the observation_set_id.
Am I doing something not right ? It seems to be working ???
jgn
· 1 year ago
You must implement it in the same fashion as the reference implementation. Do not introduce extra controller actions and/or views.
So, this means:
-- The controller/action that sets up the form must be: ObservationSetsController#show -- The form displayed by views/observation_sets/show.html.erb must be "for" the :observation model -- That form must post back to the :action => :create_observation (on ObservationSetsController)
Are you doing those things?
student1
· 1 year ago
yes, I think so.
student1
· 1 year ago
I spent sometime with this datetime_select...I can't get the seconds. I have month/day/year/hour/mintutes (as the documentation describes). There is no seconds.
I also noticed that it only works if I initialized the Observation by new (params[:observation]). If I try : @observation.observed_= params[:observation][:observed_at] the date is not set right.
Now, I am stuck with no second. I tried select_second, but that isn't the method I want.
CCC also doesn't have "seconds". Why don't we get the second field. It fields so "normal" to have the "seconds" field. It is quite frustrating.
jgn
· 1 year ago
Sadly, I'm afraid, this is one of those areas where the view helper docs are not as comprehensive as they should be.
# Creates a time select tag with a seconds field that, when POSTed, will be stored in the entry variables in # the submission_time attribute. time_select("entry", "submission_time", :include_seconds => true)
student1
· 1 year ago
Thanks....
student1
· 1 year ago
In the reference implemenation, if you click the "Delete Checked" button, and if you do not check any box (for observations), then, there will be a page telling me that something went wrong.
Keith
· 1 year ago
Looks like that is a bug.
jgn
· 1 year ago
That's a bug -- thanks.
student1
· 1 year ago
In the reference implementation, I don't see me being directed to a page to "add observation". We are supposed to save the observation set id into the user table. We save off the last observation set the user chooses. However, I don't see how we use this information.
When I log on, I get to the dashboard, which allows me to: - logout - Get a list of metrics (i.e. observation sets) - Create a new observation set - Compare
So, I don't see how and where we direct a user to a page with the most recently used observation set.
The assignment reads: "There are some small changes between this version and the prior version: 20081111021247_add_current_observation_set_id_to_user.rb adds a column to user “current_observation_set_id” - whenever you view an observation set, the id is saved here so that when you log in from a cookie, you can be redirected to that set: This makes it especially easy to enter a new observation for whatever set you were last looking at. "
So, when I log on, assuming that there's a cookie, do we not go to the dashboard, and instead go straight to the page where we can add new observation s?
Thanks
jgn
· 1 year ago
To see how you get directed to the page on which you would add an observation:
(1) Log in. (2) close your browser without logging out. (3) Go back to the application. See where you end up?
If this doesn't work for you, let us know.
Reason for this behavior: There is ONE activity that the user wants to do every day: Post data. If you have ever tracked your weight, you will do anything to avoid this behavior. Therefore, the application makes it as easy as possible.
Morris
· 1 year ago
I think I know the answer to this, but before I get around to trying it out:
This will require me to modify my browser settings to accept persistent cookies, won't it?
(But shouldn't it work equally well to leave the browser open and simply close the tab or window that's connected to the metrics mine, and then go back to the application?)
jgn
· 1 year ago
You may be able to set an exception to allow a persistent cookie from one site (e.g., metricsmine.plugh.org); or, perhaps better, localhost.
I am not 100% about this, but I think if you close all tabs to a site, and then re-open a tab, your prior session cookie will still be used (which makes sense from many typical end-user cases -- if you accidentally close a tab, you don't want to have to re-log in).
Also, it is worth nothing that Internet Explorer and Firefox work differently with temporary cookies (not your question, but related). You can block a temp cookie on IE, but not, to my knowledge, on FF (though doubtless there is a browser plugin for FF that will do it). Also, if you're a security zealot, IE implements P3P, which is pretty great, though few sites implement it server side (one that does is my old company, h3.com - https://www.h3.com).
Morris
· 1 year ago
OK, a question about the user-interface design of this:
Why would we want to limit this convenience feature to people auto-logging-in with a persistent cookie? Isn't the redirection to the current observation set equally (or more) useful to someone who logs in daily from their public library or school's lab, or someone travelling around the world tracking their latitude in Internet cafes? The way I use my own computer, taking me from the home page to the desired observation set is of almost no use at all, first because my browser discards persistent cookies on exit for privacy reasons, and second because for sites that I visit frequently, my bookmarks generally take me not to the home page of a site, but directly to the page I'm interested in (and if those pages require login, most well-designed sites will redirect me to a login page and then from the login send me directly to the page I was trying to get to).
jgn
· 1 year ago
That sounds reasonable. The way it is implemented this way is because the notion is that you want to log in + go to your "home" in an environment where you are most "at home" (where you dropped a persistent cookie).
If you logged in at school on a computer where you didn't have a cookie, do you want someone looking over your shoulder to know right away that you've blown your diet?
It is definitely the kind of thing that would get tuned based on user response.
student1
· 1 year ago
This doesn't work. I am using FF 3.0 It takes me to the dashboard.
BTW, why do you need o save the information in the database as well as in the cookie ? I thought that if you save it in the database, then once you look on, you will get the observation set information from the database. If you save it in the cookie, then you get it from the cookie. Why do we need both ?
When you say: "why do you need o save the information in the database as well as in the cookie ?", what do you mean by "the information"?
student1
· 1 year ago
I logged in as Jenny Also, "the information" is the observation_set id. I thought we're supposed to save off the last used observation_set id somewhere, so that when the user log on again, he gets send to the page whereby he can add a new observation for the observation set he last used.
Now as an admin I also noticed that in the reference implementation, the delete also seem to have rows (observationKinds) automatically disappearing. Also, when I hit destroy for some of the ObservationKind, I to an error page.
jgn
· 1 year ago
That is correct: When you display a particular observation set, save the current observation_set_id to user.current_observation_set_id.
I cannot reproduce the "automatic" disappearance of observation kinds, or any error page. If you delete all of the observation kinds (PLEASE DON'T!) you will find that you can't create a new observation set (I think). This was discussed earlier, and we said: "An admin would never delete all of the observation kinds, so we will consider this a feature, not a bug."
I have just reset the database. If you can identify a set of seps that will produce this behavior, from login to the error, e-mail the steps to me.
student1
· 1 year ago
I was trying to delete all the metrics I created as an admin on the reference implementation. It delete multiples rows for each delete key I hit. I hope that you can reproduce this. Perhaps my problem with ObservationKind delete is related or similar.
jgn
· 1 year ago
I don't understand what you're saying, because you're not using the language of the application.
If you are deleting observations (metrics), you would use the checkbox and then click "delete checked." There is only one button here, so I don't know what you mean by "each delete key I hit."
If you are deleting observation kinds -- "kinds of metrics" in the UI -- you would be clicking the delete link.
Note that when an observation kind is deleted, then the display of the KIND at the top of the "show" page for the observation set can no longer display the kind. So it is blank. There is an instruction regarding this in the static page for the "show" template.
Rachel
· 1 year ago
Can you provide me some guidance on how to dynamically change the background color of the newly added row on the create_observation page. I'm struggling what to use to help determine if the row should be highlighted. Thanks.
jgn
· 1 year ago
Well, here's what we say above (and I'll add some annotations in square brackets):
In the reference implementation, the id of the newly-created observation is put into the flash [did you do this?], so that when the list of observations is re-displayed, we can change the background color of the row [Have you figured out how to do this?]. You need to do this, too; to get it to happen you will want to dynamically change the style element on the correct <tr> tag [do you have a way to determine the correct <tr> tag?]. E.g., it would look like:
<tr>
when the row shouldn’t be emphasized; and
<tr style=”background-color: #E0FFFF”>
when it should be emphasized. This is the sort of thing you can glean from view/source for the reference implementation.
---------------------
So this means that when you display the <tr> element for the row, you are going to have some code more or less like this:
<tr <%= if SOMETHING then '' else 'style="background-color: #E0FFFF"' end %>>
The part after the "then" is when the condition holds -- i.e., when it's an ordinary row; the part after the "else" is for when the condition doesn't hold, which would be the case when you want to "decorate" the row. There are other ways to get the effect: You could create an actual style and then select it with the "class" attribute on the tr element.
The "EOFFFF" is from inspecting the rendered HTML of the the reference implementation (after adding an observation).
You have to figure out SOMETHING. It is an expression based on the whatever you put in the flash that indicates the item number of the most-recently-added observation.
Morris
· 1 year ago
Thinking about this, I realize that if you're putting something in the flash, you must be REDIRECTING to show, in the reference implementation. In my implementation, the last thing create_observation does is to RENDER show. This allows me to bypass the flash, and just make sure that my newly-created observation is an instance variable, which I need to do anyway, to be able to display error messages for the create-observation form. This seems easier to me -- is there any particular advantage to getting back to show via a redirect? As far as I can see, the user can't tell the difference, because the resulting URL is the same.
jgn
· 1 year ago
In your impl, what happens if you re-load the page (control-R) after you've rendered rather than redirected?
Morris
· 1 year ago
Yes, I realized the problem after posting, while eating supper. If you're modifying your database based on the URL or on POST form data, you must redirect to display the results, to keep a refresh from repeating the action. I got distracted from this basic point because in some cases we're re-rendering the page with errors, without redirecting but also without modifying the database.
jgn
· 1 year ago
So, the idea is this:
-- If there are errors, render. Why? Because you use the instance variables to trigger to the error display. -- If there are no errors, then you want to redirect so that the user gets a fresh page and a page reload won't re-submit the form.
Other frameworks will redirect for error display, too; the reason Rails doesn't is presumably because it means using the session too much.
swithin
· 1 year ago
I am getting the following error when submitting "Create" forms: "You have a nil object when you didn't expect it! The error occurred while evaluating nil.has_key?"
I have gone through the book many times, through your Lecture 9 slides, reviewed the "CRUD" application code (which all runs just fine on my machine).
To try and fix this issue, I am working with the admin's Measurements "New Measurement" form, which is the simplest.
The HTML produced on my form is identical to that on metricsmine.plugh.org. So there must be a problem on the "measurement.rb" or "measurements_controller.rb".
The error is being thrown by the following line in the "def Create": @measurement = Measurement.new(params[:measurement]) If I remove the code that does the create / insert, and just pass the #{params[:measurement]} to the "flash" message on the index page, then the results of that printed variable are: nameasd (where I typed "asd" into the name field).
For the above I had not initialized any variables in the "def new" with any variables. If I add def new @measurement = Measurement.new end to the controller, then I can't even get to the "New Measurement" form at all. Clicking on the "New Measurement" link gives me the error: wrong number of arguments (0 for 1)
Otherwise, I am progressing, but I've been picking at this one crucial issue for too long now. Please assist. Thank you.
jgn
· 1 year ago
Three things:
(1) In views/measurements/new.html.erb: What does your "form_for" line look like?
(2)
Double-check that your Measurement model, defined in measurement.rb, looks like this (this is what we handed out with the "solution" for the associations and validations milestone):
(3) Remove your file db/development.sqlite3 and re-run your migrations from scratch. Important: you should be using the model definitions (with its associations and validations) and migrations from the solution download.
swithin
· 1 year ago
1) I assumed that my "form_for" was good, given that it is returning the exact same HTML as the Plugh site.
2) HOWEVER, I found the following in my measurement.rb. Once I removed it, then everything worked fine. def initialize(measurement) @measurement = measurement @name = name end I must have added this when in my "I'll try anything" stage.
3)...
Thank you!
jgn
· 1 year ago
Whew -- so what that was doing was setting @name to nil. And thus your error message from before.
rajatbaner
· 1 year ago
This may be a really obtuse question, but i'm stuck on the very basics. I think i've made the app\views\observation_sets\new.html.erb file properly, and also filled in the underlying observation_set controller (Even added a dummy function called "create" to the helper object), but as far as I can tell, none of those code blocks run.
Is there a way to print debug info out to the console or something? I want to see some errors at least, or find out where my mistake is.
jgn
· 1 year ago
Well, the console already logs the name of the controller that is picked as well as the contents of the params hash.
You say that you created a CREATE "function" (I assume you mean method?) in a helper object. Action methods should be on the CONTROLLER, not on any helper objects.
So, the upshot is:
(1) In the observation_set.rb file, which defines ObservationSetController, you should define a "create" method. This is the method that allows you to create a set of observations. It will look something like this:
def create # you add your code here end
(2) When a specific observation is added, that is handled by a method called create_observation. So in that same file you will need:
def create_observation # you add your code here end
In both of these methods, you may find it helpful to add calls to the "puts" method to dump whatever debug code you want to the console.
One last thing: Everything I've said here I said in the assignment description above in the section that starts: "Controller: ObservationSetsController Notice that this controller manages updates of BOTH ObservationSet and Observation. This is not an unusual pattern. Since Observation is almost completely a “slave” of ObservationSet, it is convenient to manage both Models in the same controller. When we get to REST, we will talk about changing this."
And then I went on to define exactly the methods you need to define. I am not sure what you mean in your post about writing a "dummy function" (there are no functions per se in Ruby) or "the helper object" (since you really shouldn't need to do anything with helpers).
rajatbaner
· 1 year ago
Thank you, I'm on the right track now. It is so hard to drop the C/C++ conventions when using that stuff every day! Thanks.
Morris
· 1 year ago
I notice that Metrics Mine, as specified and as implemented in the reference implementation, doesn't use the user_id of an observation_set, except for choosing which observation sets to display on the observation_sets/index page. By editing URLs, I can easily view and edit the metrics of other users. Is it correct that for this assignment, we shouldn't be worrying about this? I thought of this because I was looking back at Milestone 2, and trying to figure out where I would have used finds numbers 4 and 5, which say, "Ensure that the observation_set is owned by a particular user."
jgn
· 1 year ago
You can skip that requirement -- I forgot to implement it in the reference implementation! I'll note that in the next lecture.
For the final project: A great thing to do is to try to manage URLs so that they aren't sequential numbers. Even if you check the user who supposedly owns a given resource/item, it can be good to not even reveal the fact that something exists at a certain id. To do this, you would add a column and you would set it to some String version of a Hash of unique info for that record; then look up by that added id, rather than by the primary key.
student
· 1 year ago
I trying to test validation on observation_sets/create_observation and I left blank amount and notes. I received the following error: Couldn't find rollup for observation at Application Trace | Framework Trace | Full Trace app/models/observation.rb:36:in `before_validation' app/controllers/observation_sets_controller.rb:53:in `create_observation'
I could not figure out why? Could you guide me?
jgn
· 1 year ago
Before an observation is validate, a row from the rollups table is looked up based on the "observed_at" value for the observation.
If "observed_at" is bad, then no row will be found, and that code will fail.
Therefore, double-check that you are setting observed_at is being set properly.
There are only rollups for dates between 2008 and 2010 -- so there could be an issue if you add an observation farther in the future. If you look at the rollups migration, you should be able to figure out how to create more rollup data for more years in the future.
sconnall
· 1 year ago
Not sure if this was resolved or not, but... I noticed that in the reference implementation that the date on the observation_set SHOW page is not the actual date and time. Is this intentional? I did see mention at the end of this blog about adding some Timezone support for the final project, but didn't want to jump into that at the moment. In the interim I've added something that displays the correct local date & time to the datetime_select. I just wanted to check if there was a reason why the reference implementation displays the date & time the way it does and if it's ok for mine to be different.
jgn
· 1 year ago
The times are in UTC (like Greenwich Mean Time [GMT]). All data is stored in the database in this format. For the final project, you could choose to DISPLAY such data in the time zone for a specific locale.
But, generally, you want to store time/date data in UTC.
sconnall
· 1 year ago
Oh, I understand now. Thanks. I used DateTime.now as the default on the datetime_select and would have to convert any dates that I store in the DB back to UTC format. Probably not worth the effort and best accomplished using Timezone support. Thanks for the quick reply.
jgn
· 1 year ago
You shouldn't need to use DateTime.now at all! See what happens if you don't "pre-fill" that field.
Also: It is easy to create UTC times . . . you might have noticed in models/rollup.rb, db/migrate/data_add_rollups.rb and elsewhere.
In other words: If you stick to UTC, you don't have to do any conversions.
sconnall
· 1 year ago
I've removed it and the datetime is back in UTC time. Now that you've explained it to me it makes perfect sense.
Greg
· 1 year ago
Can you comment on what we need to package and submit to our TA for assignment III? Thanks.
jgn
· 1 year ago
I have a longer page coming regarding grading, etc., and I am waiting for the TA's to finish reviewing it.
The submission is like so:
0. Before submitting, verify that the migrations work! I.e., delete (or rename) db/development.sqlite3 and do "rake db:migrate". Check out your app! It can happen that you are relying on bad data being in the database, so exercise your app with a clean slate.
1. There should be a small readme text file in the root of the project with your name, e-mail address, and the name of the project -- this is simply so that if we change the name of your project we can still figure out whose it is!
2. If you are doing anything "unusual" or have bugs that require special discussion, include that discussion in the readme. There is NOT a requirement for a "writeup" for this assignment, because the assignment is essentially about fulfilling a fairly narrow set of requirements. Do include judicious code comments for anything that is unusual, weird, especially superb, etc.
3. You may have a file bin/PKZIPC.exe - remove it. Your ZIP won't go through some e-mail agents with it included.
4. ZIP your project with
rake package
It is possible that this will fail on systems that do not have a working ZIP program -- we have a ZIP in Ruby included, but it can sometimes break on Windows.
If rake package doesn't work, ZIP up your project with any ZIP program. If you have to manually ZIP, remove the files from tmp/ and log/ . INCLUDE YOUR NAME in the name of the ZIP archive.
E-mail it to your TA.
Morris
· 1 year ago
So we should ignore the "e168:submit" task shown by rake -T, described as " E168: Create ZIP for submission"?
Also, you say we should delete our database and rake db:migrate. Do you want us to package our submission with our test data in the database, or just a clean database, or none at all? Or does this even matter?
jgn
· 1 year ago
Let me get back to you on e168:submit - I need to take a 2nd look at the rake script.
The safest thing would be to rename your "good" database. So that way if it turns out that your migrations fail, we can still do some forensics to figure out what's going on.
I need to double-check the Rakefile 'cos it may do something funny with db/
John
xtine78
· 1 year ago
observation_kind and unit have the same relationship to measurements right?
For an observation kind I can say something like observation_kind.measurement.name because all the methods are made available to the observation_kind through the measurement relationship.
Should I also be able to use the same relationship with units? For example unit.measurement.name? When I do this from the unit's index view the measurement is nil.
jgn
· 1 year ago
Could you double-check that from the console for a unit that we created in the original migrations? E.g.,
I.e., iterate through all of your units, and see if any break on the following of the measurement association.
xtine78
· 1 year ago
I ran migrations back and its working better.
jgn
· 1 year ago
Good - you should review your code carefully, though, 'cos it sounds like you got some bad data in there.
akv
· 1 year ago
Unit/Kind of Metric Edit functionality. The page is functional, but there is a warning in the app that says - We know you'd like to change the measurement, but since these are shared, the measurement needs to stay the same.) Should we implement the same behavior in our application
jgn
· 1 year ago
Please do!
swithin
· 1 year ago
If there is a time difference between the default time on one of the MetricsMine.Plugh.Org "add new" forms and my own, then should I synch my copy to that?
jgn
· 1 year ago
No.
One thing you want to watch for is this:
-- If in your own implementation you add an observation at 5:00 PM, it should show up as 5:00 PM in the list.
What is going on here is that times are stored in the database in UTC (universal time). If you made the mistake of entering dates in, say, local time, you could get a discrepancy.
How does this line work? :observation_ids[] isn't something I have seen in my code. Is this meant to gather the observation.id into an array? I gather that the obs.id will send the obs.id to the update method so that an observation can be deleted.
jgn
· 1 year ago
I discussed it at some length in one of the lectures, and said things like "you will need to understand this for Assignment 3."
The checkbox technique is also used in ChildCare Co-Op. Please review those materials.
xtine78
· 1 year ago
I do have it implemented and working (not exactly as written above of course). I will do some more research to make sure I understand how its working. In the end, its probably my update method that isn't handling the information correctly.
Thanks!
jgn
· 1 year ago
Cool.
The short answer is that when you put [] after an attribute name, Rails will magically take each check and assign "true" to the array element for the check id.
It's totally non-obvious, which is why I discussed it in lecture, and recommended that people look at the ChildCare Co-Op code.
swithin
· 1 year ago
I can't seem to grab the variables submitted by the "datetime_select" helper. The dynamically created HTML in the overall form looks correct: <form action="/observation_sets/create_observation" method="post"> <input class="text large" id="observation_notes" name="observation[notes]" size="30" type="text" /> <select id="observation_date_1i" name="observation[date(1i)]"> ... and all the other (2i), (3i)... fields </form>
I can grab the "observation[notes]" field (shown above) just fine, but for some reason just keep getting nil values when trying to work with the "observation[date(1i)]" fields.
params[:observation][:notes] grabs the notes, but params[:observation][:date] won't grab any dates... and params[:observation][:date(3i)] throws an error.
Played around with convert_date to no avail.
This has got to be simpler than I am making it. Probably a one-liner...?
Stu
· 1 year ago
I don't think you need to access the fields individually unless you want to modify them before insertion. According to John you shouldn't modify the date fields at all as they are in UTC format and should be inserted/updated as UTC in the database. When I do my new I pass the entire object and it synchs up all of the fields from the form when it does the insert. I'm checking to see if I have to do any form field editing, so this may change, but I hope that I can have that all done prior to the create_observation new is invoked. Actually, I think the database validations should catch all these if they're defined correctly. Take a look at the invitations_controller in the CCC app to see what I'm talking about with regards to passing the entire object to the new.
jgn
· 1 year ago
Right, you shouldn't have to do anything.
Incidentally, at work we have noticed that there are problems with datetime_select on Rails 2.2.2, so I hope you haven't inadvertently updated your Rails version!
If you continue to have problems, post.
Stu
· 1 year ago
I'm having a problem with one of my "field too long" checks which is kind of odd. I have my validates_length_of set correctly and an error_messages_for and error_message_on my observation_kind new.html.erb form and I get a nil object error when the name value is 31+ in length. I'm doing exactly what I do for other forms and it works fine elsewhere. Does anything pop out in anyone's mind why this might occur? It's sort of look's like an array out of bound situation (I'm guessing). The strange thing is that the stack trace shows that it's in the collection_select for the measurement names. I'll keep looking for what i've done wrong here.
It is hard to tell w/o seeing the view and controller code. Can you email your TA?
sconnall
· 1 year ago
I'll send it right over to you.
Keith
· 1 year ago
Rails rolls up the data in these multi-part fields for you -- you can access it using params[:observation][:date], and send it to the db like that.
Morris
· 1 year ago
You shouldn't even need to access params[:observation][:date]. If you name the field appropriately in the call to datetime_select, so that it's the name of a column in the observations table, then you can just call Observation.new(params[:observation]), and by the magic of Rails, everything gets unpacked just right.
But: to figure out what's happening with parameters, in general, I've found it very useful, when I get totally confused, to stick the line
puts params.inspect
into a controller action, and then go look at the output from my server, to see exactly what it is that the controller is seeing after the user posts the form.
Keith
· 1 year ago
Morris is more correct than he realizes. It is ActiveRecord that correctly interprets your multi-part data; if you try to access the params hash in the controller using the key I specified above, you'll get a nil value. At that point it is still just a hash. Once you pass the parameters to Observation.new, then AR will handle the input correctly.
In general you want to construct your forms so you rarely, if ever, need to futz with the parameters, especially in basic CRUD actions.
I'm getting a lot of questions from people having trouble with params. Outputting it with params.inspect, tailing your development log, whatever -- it is important to know what is being passed to your action, and what the structure of the hash looks like, in order to debug effectively.
swithin
· 1 year ago
I tried that params[:observation][:observed_at] as well as Observation.new(params[:observation][:observed_at]) (ie. the "date" field is renamed in this application to "observed_at") and it just does not work.
I just keep gettting an error "Couldn't find rollup for observation at " The date is not being received at all.
In the error message there is a "Request Parameters" section that shows clearly that the parameters are getting sent across correctly as follows: {"observation"=>{"observation_set_id"=>"2", "observed_at(4i)"=>"04", "observed_at(5i)"=>"31", "observed_at(6i)"=>"45", "notes"=>"abc", "amount"=>"123", "observed_at(1i)"=>"2008", "observed_at(2i)"=>"12", "observed_at(3i)"=>"7"}, "commit"=>"Add"}
I think there may be something wrong with my system's helpers when they are catching and reconstituting the date fragments.
I will send my code to Keith right now.
Morris
· 1 year ago
Observation.new() should create a new Observation object, right? So the params hash that you pass to new() should be a set of attributes of that object, i.e. in this case, attributes of the Observation class. params[:observation] is an appropriate such hash, but params[:observation][:observed_at] is just the parameters for the observed_at field, You might be able to get away with something like
but why go to the trouble of addressing this level of detail when creating your observation? You have everything you need in params[:observation] -- the observation_set_id, notes, amount, and all of the pieces of observed_at. Just invoke Observation.new(params[:observation]), and trust Rails to unpack everything properly for you.
Keith
· 1 year ago
My point, as I noted below, is that you cannot access params[:observation][:observed_at]. Rails is smart, but not that smart -- those parameters are unpacked by ActiveRecord. There is no key :observed_at in the params hash in the controller -- dump the hash in the console and try accessing it! It will give you a nil. You're right in that you don't want to mess with these multi-part data types in the controller, but what I originally said was incorrect about how to access it if so inclined.
As I said, generally, you want to build your forms so you can do as you described, and mess with parameters only on rare occasions.
jgn
· 1 year ago
Right.
Naturally, I've been watching this discussion of datetime_select with some interest.
My main comment for students struggling with datetime_select is to look at example code:
In the ChildCare Co-Op app, app/views/playdates/list.html.erb . . . and app/controllers/playdates_controller.rb (see the "create" action).
As you see there, datetime_select does all of the heavy leifting -- you don't have to dig into the key of the instance object, nor its pieces.
The one additional piece here is that there is an option :include_seconds which is documented for other tags; despite its omission from the docs for datetime_select, it does exist. I sent around an e-mail on this topic awhile back.
Dave Byrne
· 1 year ago
FYI It looks like the reference implementation generates a server 500 internal error if you try to view a rollup for an observation set with no observations.
jgn
· 1 year ago
Good catch -- I will fix that. That doesn't affect anything you need to do for submission.
jgn
· 1 year ago
I fixed it in the reference implementation (reset the db, too). It will take a bit more work to fix that on http://www.metricsmine.com so I will leave that server alone for now.
Thanks!
katemuse
· 1 year ago
Hello!
My tests complained that a new ObservationKind was created without a :measurement_id value. My ObservationKind model file includes "validates_presence_of :measurement_id".
First, it looks like the validation isn't working. Wha?
Second, I started a new migration, adding ":null => false" as an option to change_column: change_column :observation_kinds, :measurement_id, :null => false
but the migration failed with the message, -- change_column(:observation_kinds, :measurement_id, {:null=>false}) rake aborted! undefined method `to_sym' for {:null=>false}:Hash
WHA??? this seems nuts! any suggestions? thanks.
jgn
· 1 year ago
You shouldn't need to change any associations or validations on the models, so I would recommend removing validates_presence_of :measurement_id - if you do leave it in, it is critical that your code run with the original migrations; if the original migrations (or automated tests) don't work, remove it for sure.
The reason your call to change_column is failing is because you left out the type: See the doc;
I just wanted to confirm that you can't change the unit of a measurement, even if you create a new unit and associate it with the same measurement. Is this true? Should we enable to user to select a different unit of measurement, or are we stuck with the first, "preferred" unit? For example in the reference application I created a new unit "corpses" to be used for a certain kind of measurement of "bodies" and created a new "bugs_measured_in_corpses" observation kind, but could only, in truth, measure it in "units" -- the first unit created with "bodies" as the measurement type.
jgn
· 1 year ago
At present, once a unit is created, you can only change its name.
Also, when an observation is created, the unit should be the same as the preferred unit as the observation set for which it is created. This is specified in the assignment: "An Observation has a Unit. In the initial implementation, all Observations in a particular Observation Set use the Observation Set’s preferred unit. (E.g., if the Observation Set’s preferred unit is Pound, then all Observations are also in Pounds.)" (http://e168f08.plugh.org/assignments/assignment...).
Eventually, it would be nice if one observation could be recorded in pounds, and then later in kilograms, with automatic conversions between units of the same measurement kind.
Also, at present, when you create an observation set, you never pick the unit. You only pick the KIND, and, by specification, "also set the @observation_set’s preferred unit to the first unit of the selected ObservationKind’s Measurement!!" (http://e168f08.plugh.org/assignments/assignment...). Notice that we have not defined here what "first" really means; as long as you set the observation_set's unit to SOME unit that has been associated with the measurement of the picked observation kind, you'll satisfy the requirement. I probably should have said "first in order of create time." In any case, lacking an ability to convert between units of the same measurement, it makes no sense to allow a lot of flexibility with units.
akv
· 1 year ago
can u guys bring the test app back up, it seems to have beed down for the last hour . . .
jgn
· 1 year ago
It has never been down. It has failed to render a page because people keep deleting the observation kinds! Sheesh!!
We're sorry, but something went wrong. We've been notified about this issue and we'll take a look at it shortly.
jgn
· 1 year ago
As of 7:38 PM EST - no problems from my computer. Try clearing your cookies for the metricsmine.plugh.org host.
Anonymous
· 1 year ago
Apparently, 'admin' cannot view Observation Sets . I can see it now.
Li Diaz
· 1 year ago
I have everything working, except i cant figure why my rollups arent displaying anything, except blank rows. Is there something i should be looking at that im missing? I noticed i keep getting one day ahead in the from -to date range on the rollup page, however , even by changing this or the interval i keep getting : "There's no data for that rollup" or timestamped rows with empty rows.
Li Diaz
· 1 year ago
Its working now, nevermind =)
student
· 1 year ago
John, After I run rake db:migrate VERSION=02 rake db:migrate and I received the following error message. I am not sure why? What do I need to do? ActiveRecord::RecordNotFound in WelcomeController#welcome Couldn't find User with ID=7 RAILS_ROOT: C:/Ruzh/Harvard/CSCI E-168/Assignment3
Hi, I've got a couple questions about the tests. How comprehensive are the tests in test/unit? Are we expected or required to add tests to test/functional? And finally, is there an automagic test script for this assignment? I tried rake test and it says everything is great! Granted half the files it ran were just asserting truth.
jgn
· 1 year ago
I revised the tests for the code handed out after Milestone I -- you don't have to do anything extra. They are *NOT* comprehensive. Your submission will be checked by hand. OK?
rajatbaner
· 1 year ago
Hi, I thought I was done.. Logged back in to do a final wrap up, and now I'm confused. Do we need to submit migrations? The Paragraph at the top regarding logging in from a cookie, redirecting to measurements page, makes it sound like we might need to change our migrations. I did them for Milestone 1 but haven't touched them and have been using the provided migrations from this site.
Am i right? Were we supposed to do a version 3 of the migrations? Thank you.
jgn
· 1 year ago
We just want to make sure that your migrations will work -- in all likelihood we won't run them, but sometimes people submit applications that have big problems so it is good to have to the code to reproduce the database.
There are no required changes to the migrations as long as you use the ones we handed out after Milestone 1.
Regarding using the cookie to login and to to the last observation set: That is all handled by the filter in the application.rb we originally handed out.
The only thing you have to do his this: "When an observation set is displayed or edited, the current observation set id is copied to the current user’s attribute current_observation_set_id. You must do this as well. This allows the filter on the application controller to bring the user back to the last observation set edited, for easy addition of new data." See above. This has always been in the requirements.
rajatbaner
· 1 year ago
Sounds good, thank you. I couldn't find the "redirect" code, thought it should have been in users_controller.rb, so i re-implemented it there. I'll put it in my readme. Just got off an airplane, too tired to keep searching!
burnetla
· 1 year ago
Am I the only person that is having huge problems submitting my final zip file via gmail? It seems to be flagging all ruby code as executables and I definitely don't have any exe files in there. I already contacted Harlan to let him know I was having problems but just wanted to see if anyone had similar issues.
jgn
· 1 year ago
Do you have the PKZIPC.exe file in your bin/ directory?
In several posts since the beginning of the course, I have said: Remove that file.
burnetla
· 1 year ago
No, I removed that. Over the past two weeks when I have been sending just the contents of the "controllers" directory back and forth from home/work it wouldn't allow me to send it via zip either. I had to use ".7z" to get it to go. I assume it must be flagging ".rb" files as executable because I have literally tried deleting everything. It definitely wasn't a problem with the last assignment though which is why I am even more confused.
burnetla
· 1 year ago
Okay, I actually tried zipping using a different program here on my work machine and it seems to have gone through. Of course I thought that last night when I sent it and it bounced back....
jgn
· 1 year ago
What program were you using the first time that caused the problem?
vaughanatworld
· 10 months ago
Did anyone implement the compare function for the extra credit?
I now actually look at the console output from console/server. I also see <%= debug(@order) %> from the book, which I haven't tried. But the debugging process for me seems to be very slow.
My particular scenario: I am trying to create a measurement. The controller code has something like:
@measurement.name = params[:name] (which is similar to some code in CCC, but didn't work for me)
I looked at the console output of the server, it has:
Parameters: {"commit"=>"Create", "action"=>"create", "measurement"=>{"name"=>"zzz"}, "controller"=>"measurements"}
I changed the code to:
@measurement.name = params[:measurement][:name]
and this worked. But this doesn't feel right. Am I doing something wrong ?
Thanks
You probably preceded that code with: @measurement = Measurement.new
Your code is saying:
-- Copy the value associated with the :name key in the hash under the key :measurement in the params hash to the "name" attribute of the @measurement instance variable.
BUT, the whole point of Rails's automatic handling of the params hash is that you should be able to say . . .
@measurement = Measurement.new(params[:measurement])
Why? Because the parentheses on .new will accept a hash. I.e., it could say:
@measurement = Measurement.new( :name = params[:measurement][:name])
But notice: params[:measurement] itself is EXACTLY suitable for the what is passed to .new!! It has a key called :name with the appropriate value! So this is virtually equivalent:
@measurement = Measurement.new(params[:measurement])
Note that this is covered in the required reading, in the the video of the lecture, and in the PDF of the slides, which are on the downloads page. If you study the assigned material, you will find, for instance, on Slide 54 of the PDF, or slide 73 of Hour 2 of the video for Lecture 9, a "canonical" example of how to implement the "create" method for a standard CRUD controller.
I make the point about the params hash on slide 36 during Hour 2. I really belabored the params hash and its magic through several slides -- I was quite worried about boring everyone, but I guess I was right to spend some time on it. PLEASE review the lecture. If there is anything I can do to make this more clear, please let me know, but this is super super super basic stuff.
In the book you want to take a look at figure 22.1 -- as you will recall, I added this very diagram to a slide and said how important it is. That diagram and the following page discuss EXACTLY what you are concerned about.
Parameters: {"action"=>"edit", "id"=>"1", "controller"=>"measurements"}
Measurement Load (0.000191) SELECT * FROM "measurements" WHERE ("measurements"."id" = 1)
This comes from
@measurement = Measurement.find(params[:id])
This is something done in CCC. But it seems like the SQL has measurements.id rather than id ? I am not sure what is happening.
(I also always get confused by the singular and plural)
Could you explain ?
Thanks
Recall:
Model name: Singular. Why? Because each instance of Measurement represents one measurement.
Table name: Plural. Why? Because the table contains many rows, each of which describes a single measurement. Thus the plural for the table name (measurements).
So . . . If you are manipulating an instance of Measurement, and look at the log which is showing the SQL to the database, you will see the table names . . . which are plural (if you follow the Rails conventions).
However, the ObservationKindController seems to be giving me a lot of problem.
(1) I seem to be able to create quite a few new observation kind in a row. When I click on "Kind of Metric" again, I sometimes see them all.
But, sometimes, rows seems to be automatically deleted.
I am not quite sure how to debug this.
(2) I also tried destroy. I know that my items is destroyed. I do send it to the index page after it is done.
But looking at the access to the database from the console log, not only do I see the select * from observation_kinds (from the index page - listing
the metrics kind), I also subsequently see a select for a particular observation_kind by an id that correspond to the item that has just been deleted.
So, it has been quite confusing.
The code for Observation kind is essentially a copy of the Measurement (except for the deletion). So, I am not sure what is going on.
Could one error in the destroy mess up all the subsequent operations. I actually ^C the server and restarted. But that doesn't seem to help.
The way I do destroy is:
@observation_kind = ObservationKind.find(params[:id])
@observation.destroy
Then I redirect to index (whether it is successful of not)
Is there a good way to debug ?
Thanks
I use vi to edit files. So after editing index.html.erb, I will in addition has index.htmt.erb~
I thought they were innocuous and don't bother to remove them.
After removing all these *~ file in the controller and the view/* directory, the strange behaviour disappared.
I don't know if this really is the reason why Ruby gets confused. But it seems to work now.
On the http://metricsmine.plugh.org/observation_kinds site, if I add a Metric Kind and then go to delete it, it generates an error. It says "The page you were looking for doesn't exist".
Mike C
When I was preparing the app so that various actions and views are stubbed out, I removed the "list" action in some controllers in favor of always using "index".
So . . . this is a bug.
I just fixed it.
It shoudn't affect your assignment because the "destroy" action isn't implemented in the ZIP (you implement that action).
I'm looking at the html generated by the reference app online. (http://metricsmine.plugh.org/observation_kinds)
For delete, you are generating the following javascript:
<a href="/observation_kinds/destroy/7" onclick="var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;f.submit();return false;">(delete)
In the examples we've studied thus far, (CCC, LinkWizz, etc...) I think the output looks different. When I use those formats, like so:
<%= link_to '(destroy)',:controller => :observation_kinds, :action => :destroy, :id => observationKind.id, :method => :post %>
I get the following:
a href="/observation_kinds/destroy/2?method=post">(destroy)
I guess my question is, should I be worried about the creation of the javascript snippet you have online? If so, can you point to a way to auto-create this from some Rails macro?
Thanks,
Mike C
Here is what it is doing:
-- Remember that HTTP can do a number of methods, the most common of which are GET and POST (there's also DELETE, etc.)
-- In the default case, link_to will do a GET.
-- But is a GET suitable when you want to delete something? No, it isn't. Why? If, after the GET, we did not redirect, we might bookmark the GET, and/or refresh the page, and attempt the GET again -- and thus to to the :destroy action again. This is not right.
-- What we want is a POST. link_to allows an option :method => :post
-- So, on-the-fly, Rails creates a little form so that when you click the "delete" link, you actually POST back to the server. POST is for making changes in server data.
By this means, Rails uses the appropriate HTTP method for the operation.
If you turn off JavaScript, it will use a GET (which will work, but with the dangers described above).
One of the benefits of doing it this way is that your site can more properly leverage the HTTP methods. We will talk some about this Wed. night when I go over REST.
In LinkWizz, you should see the same thing for the research_topics list. I don't think we do any deletions elsewhere.
For CCC: Is there a delete somewhere?
Rails is really finicky about braces
<%= link_to '(destroy)',:controller => :observation_kinds, :action => :destroy, :id => observationKind.id, :method => :post %>
is different, in terms of output, from:
<%= link_to '(destroy)',{:controller => :observation_kinds, :action => :destroy, :id => observationKind.id}, :method => :post %>
Notice the curly braces in the second one... this is what generates the javascript output.
Mike
I should have said... It's absolutely correct in LinkWizz. It's my user error that caused the issue. I simply did not add the curly braces. When I typed the line it, I missed them. I should have cut and pasted.... Anyway, hopefully this might help someone else.
Mike
What this is about:
There are actually two hashes at the end of link_to
The first Hash: This is for URL generation (:controller =>, :action => etc.).
The second Hash: HTML options (:method =>, :class =>, style => etc.)
I think this is an area where the docs are confusing -- note the number of different styles they use. Which hash does :method belong to? It depends on which form of link_to you are using.
Mike
link_to "(delete)", { :action => "destroy", :id => kind.id }, { :method => :post }
Now according to the docs the following is the method signature for link_to:
link_to(name, options = {}, html_options = nil)
This would indicate that :method is one of the html_options. Yet under the 'Options' heading it lists 4 options:
:confirm
:popup
:method
html_options
This would indicate that it is one of the options. This is all very confusing.
Also:
I think Morris pointed this out: In lecture or possibly a comment here, I suggested that the :method => :post was on the first options hash, not the html_options hash, and possibly that the JavaScript is created as a result of something in the first options hash. But it is in fact the :method => :post in the 2nd hash that triggers the fancy JavaScript.
http://api.rubyonrails.org/classes/ActionView/H...
What they are giving under "Options" -- namely, options with keys such as :confirm, :popup, and, crucially, :method, are all for the 2nd (html_options) Hash.
For the first Hash, you are supposed to look at the options for url_for.
But there is no indicator I can see that the options for link_for are specifically for that second (html_options) Hash.
For what it's worth, the discussion in AWDR is quite clear. In the latest PDF, that's on page 495. On p. 496 :method is discussed, and how it works to force a POST even though it's a link.
(1) Is the UTC in your timestamp on your metricmine page printed by some specific time helper method.
I didn't find a particular simple method that prints out the time stamp the way you have it on our web pages.
I use for to_formatted_s (which does not have UTC, and it is not in UTC) time.
There were suggestions of strfttime...but they also, isn't exactly like yours ?
(2) My button looks different from yours. You have a blue button, and it is retangular. Mine has round edges. Is there a css style sheet we should use.
I already have one public/stylesheets/layout.css
Thanks
(2) Do not change the layout; do not change the CSS. The basic page layout comes from views/layouts/application.html.erb, and that loads CSS from public/stylesheets - it should look roughly the same. If you like, e-mail me a screenshot.
ALSO, are you basing your new work on the latest download?
Yes -- Just using the default output there. I wanted to make sure we were talking about a specific display.
Elsewhere, it can be convenient to use the strftime method on a datetime object, e.g., something.created_at.strftime('%d-%b-%y')
Incidentally, the standard practice is to store datetimes in UTC in the database. Then tailor it for the user, according to their wishes. Here's an interesting blog post on how to do it for Rails 2.1 -- we are thinking about making time zone support an option for the final project:
http://mad.ly/2008/04/09/rails-21-time-zone-sup...
In the supplied material as I've downloaded it, the stylesheets directory contains 8 stylesheets, and the application layout in the layouts directory references 7 of them.
If you "view source" with your browser on any page that has a button, for example the users/login page, you can see the HTML for the rectangular blue button, and the corresponding .html.erb file for that view will show you the Rails code that generates that HTML.
I have a question about the preferred_unit... I'm not sure of the purpose for it... the data model calls for unit_id. The migrations use it in establishing the relationship between observation_sets and units. But where is it supposed to be stored? How is it accessed? And for what purpose?
Mike
The idea is that an observation can be made with a different unit.
Say I'm in England. I weigh myself on a scale, and get my weight in kg or stone. I would like to be able to add that observation. At present we don't allow this in the UI.
Obviously, if the observation set has one unit, and an observation (in that set) has a different unit, it is important that both units have the same measurement (e.g., weight - you wouldn't want to have an observation_set with a unit in, say, feet, and an observation in pounds, 'cos those are two different measurements, length and weight, and thus aren't comparable). This isn't enforced now. Sometimes the schema is a bit in advance of the product.
Now, why the preferred unit: The idea is that the observation_set has a "recommendation" for the unit for all observations that are made under that observation_set.
The upshot of this is:
(1) When an observation set is created, set the preferred unit to the first unit available for the measurement of the observation kind from which the observation set is being created.
(2) When an observation is created, use the unit from the observation set.
I think there might be a gap in the implementation where the unit_id is not being set right when an observation is created -- I'll double check that, too.
Thank you.
But shouldn't there be a preferred_unit column in the observation_sets table? (There isn't one).
That is,
"(1) When an observation set is created, set the preferred unit to the first unit available for the measurement of the observation kind from which the observation set is being created."
I'm definitely doing this... and I am saving the record.... then I'm redirecting to the index page... and it starts to create the page, but dies because it can not find form.preferred_unit.name...
So it goes...
Mike
On ObservationSet:
belongs_to :preferred_unit, :class_name => 'Unit', :foreign_key => 'unit_id' # 4a
I think I got that right.
My error was being caused by a data mismatch in the tables. I had gotten things a tad out of sync while developing... So, there had been no matching rec in the units table to be found from observation_sets. Hence, it was causing a nil error. That part is working now.
I'm a bit confused still on the association name... I see that I can use the name to access the data in the remote table. But, I do not see what code is being executed to get there. I had expected to find some generated code (somewhere) based upon the "belongs_to" in the model. But there wasn't any (that I could find)... I could see the preferred_unit as a method from observation_sets... Where is this method defined?
Mike
Arguably, the association does not need to be called "preferred_unit" but we did that for the assignment to . . . make it a bit more challenging. It's the only case in MetricsMine where the association name isn't conventional. Hence, the use of :class_name and :foreign_key
Actually, it appears that it's :method option that does this, not the :action. See pp. 495-496 in AWDR, and notice that :method is an HTML option (not at all clear in the Rdoc).
Basically I want what we give you to stay the same, so that when we're grading, we're not bewildered by a strange-looking interface. On occasion a student creates a new stylesheet or goes way overboard in streamlining the interface. But that's not what this course is about, so it is wasted effort, and possibly something that jeopardizes our ability to grade.
You should be able to skip extraneous markup (such as empty <div>'s) in what you implement. It may be, however, that it is doing some structuring that isn't immediately apparent.
Incidentally, the teaching staff uses Firefox, so if it looks ok in FF, I think you're ok -- no need to check with Internet Explorer, Opera, or other browser.
Here is an example for Measurement
id = params[:id]
units = Unit.find(:all, :conditions => ["measurement_id = :id", {:id => id}])
observation_kinds = ObservationKind.find(:all, :conditions => ["measurement_id = :id", {:id => id}])
@measurement = Measurement.find(params[:id])
if units.size == 0 && observation_kinds.size == 0
if @measurement.destroy
flash[:notice] = 'Your measurement was successfully deleted.'
else
flash[:error] = 'Failed to delete measurement.'
end
else
flash[:notice] = "Measure #{@measurement.name} cannot be deleted,
You must delete all Units and/or Observation kinds that reference it first."
end
If you will look at the reference implementation -- or at the static HTML -- you will see that we don't provide a means to delete a measurement. This is deliberate, because if you deleted one, it would cause havoc with existing observations.
This was a design choice. To be sure, your strategy would be a decent way to prevent such havoc and allow the deletion of a Measurement . . .
BUT, we do not want you to implement more than the requirements!
Please, do not implement extra functionality. Do a great job on what is required.
John
Looks like my strange deletion problem is back. I really do see (something/someone) automatically deleting my observation_kind. While I was adding in a few measurement_kind (without deletion), one of them magically got deleted..
I have a snippet of the log when this happend. Would you be able to look at that. I have sent it to my TA as well. But in case you get a chance to look at it sooner, then I could proceed with the other part of the assignment.
I also noticed that in my log, there seems to be 2 sessionIDs:
Session ID: BAh7CToMdXNlcl9pZGkMOg1pc19hZG1pblQ6D3VzZXJfbG9naW4iCmFkbWlu
IgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVyOjpGbGFzaDo6Rmxhc2hIYXNo
ewY6C25vdGljZSIkWW91ciBraW5kIG9mIG1ldHJpY3MgaXMgY3JlYXRlZAY6
CkB1c2VkewY7CUY=--b6c94f16882989fe21d2a65e2858309809d2bab9
and
Session ID: BAh7CToMdXNlcl9pZGkMOg1pc19hZG1pblQ6D3VzZXJfbG9naW4iCmFkbWlu
IgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVyOjpGbGFzaDo6Rmxhc2hIYXNo
ewAGOgpAdXNlZHsA--be4e8371b9d302dd85b0ac0760e4566253c95e04
Either there are 2 sessions going on without me noticing (I only run 1 session at a time), or this is normal.
I use only 1 tab in the same browser as far as I know.
In any case, I didn't do any deletion during the session, and a row just disappeared.
Do you have any suggestion on where to look ? This problem has been going on, but it was intermitten.
One thing that could be happening is that somewhere you are redirecting to the wrong page -- or, possibly, you are calling a method in your controller twice.
Why don't you go on to the other parts of the assignment anyway? I don't think you should let this hold you up.
The Session ID are not the same. One has 3 lines, the other 4. The 3rd line is different. I am not sure why one has a much longer ID.
I redirected to the correct page. The TA has seen that code at the time the problem appeared the first time. And this time, I didn't even do a deletion while adding in more observation_kind. But this IS strange.
So: I don't think this has anything to do with your sessions.
Review your code for adding a measurement. Are you accidentally calling a method to delete a measurement?
I understand why you say, for instance, that you "redirected to the correct page." However, you have a bug, so it is futile to claim that your code is correct. You need to keep looking at it.
Note that if you created a user, but the database was reset, the code that handles the cookie creates an error.
I will fix that tonight -- it's a bug.
In the meantime, remove your cookies for the metricsmine.plugh.org site -- in Firefox:
Preferences / Privacy / Show Cookies / search for metricsmine
Then delete any cookies you see.
<%= content_tag :table do %>
<% some_collection.each { |x| %> <%= content_tag :tr, (content_tag :td, h(x.name)) %> <% } %>
<% end %>
vs.
<table>
<% some_collection.each { |x| %> <tr><td><%=h x.name %></td></tr><% } %>
</table>
Are there any easy-to-think-of cases where it makes sense to use the generic "tag" or "content_tag" instead of the raw HTML?
I think in those examples we take advantage of as many helpers as possible, except for when, as you suggest, the plain HTML is probably more obvious -- and more friendly to a designer. One helper that either didn't exist in 1.2 or I missed what the helper to handle labels. I wish I had used that in LinkWizz, etc.
Do you mean the reference DB used for checking whether or not your migrations and associations were good? You should not be using that as a guide for how values should be set up in the database.
Users do need to be able to enter an observation for any time -- are you having trouble with the form.datetime_select helper?
John
I'm not sure about the question -- in the reference implementation and in the static version of the page, the hour, time, and seconds are there as drop-downs, right?
Am I missing something?
Same situation will apply when trying to create a new Metrics, should we raise an exception or display a message say that you need to define observation kinds first. http://metricsmine.plugh.org implementation seems no to handle this situation.
Note that the only person who can delete an Observation Kind is an admin. Presumably the admin knows that if all observation kinds are deleted, then the application would fail in this regard. So . . . we will consider this a bug rather than a feature, on the assumption that the admins would not willy-nilly delete Measurement Kinds.
Admins, do not delete all of your Measurement Kinds!
<%# Next line should show metric kind dynamically; if
# it's null, show nothing.
%>
Metric kind: personal weight
You can verify the behavior with the reference implementation.
Is the comment clear? This is from views/observation_sets/show.html.erb
But after searching lecture 8, 9, 10 several times and and api.rubyonrails.com, I fail to find this.
I was looking under text_field.
If we really could do so, could you point me to the information. Thanks.
Validations are declared on the model. I explained how these validations worked a few lectures ago.
If you will take a look at the Observation model in the latest download, you will see that the following has already been declared for you:
validates_numericality_of :amount
If you want to display the results of that validation, you will need to use the error display helpers -- for examples of that, see CCC or LinkWizz, or the lecture slides.
(1) The form itself does not have anywhere one could change the observation_set_id to begin with.
So, I don't know how the user can change this.
(2) So far, I have been embedding them in a instance variable. Is that okay ?
The way I get to adding an observation is by clicking on an observation set, in the list of observation sets.
So, as a result, I get into the controller knowing the observation_set_id.
At that point, I can set an instance variable which passes to the view.
The view will go back to the controller by setting a parameter using that above instance variable.
as in:
<% form_for :observation_set, :url => { :action => :create_observation, :id => @observation_set.id }
Does this not work ? Or should we set the instance variable instead.
I have a different questions. The time in creating observation - there are broken up into 6 fields. Each of the time related field does not
by itself correspond to an attribute for the observation. So, I simply create a different hash altogether.
Does that sound reasonable ? I use "select" to generate the options for hour/min/sec/year/day. But I don't see a month_selection helper.
I wound up using html. Is this expected ? This seems to work, but I have a feeling that the month_selection is often used, so there may be some method I am missing. Am I doing it right ?
Look at date_select and datetime_select; there is no need to generate html. Rails will convert the data passed in from those selectors into data that is compatible with the database.
The hidden field is to store the observation_set_id. However, I put that in an instance variable. THe way I get to the observation creation is by clicking from an observation set list, so I don't see where I would need one.
So, some comes in the view as an @observaion_set
The view does what it needs to do,
but, with :id => @observation_set.id, the params[id] is now set to what comes into this view as @obervsationse
So, in summary,
a <value> comes into the view as an instance variable
The value is placed into :id => <value> and send to the controller.
The controller then reads the <value> from params[:id]
Is this not okay ?
Thanks,
No. The observation_set_id on the observation should be set to the observation_set.id. There are two id's in play, one for an observation, the other for an observation set.
When you display a form to create an observation, do you know the id that the database will give a new observation when the form is displayed? No, you don't. The id should not be specified at all for the :create action, because when the create action takes over, it will get the new id from the database.
Would you e-mail me privately? john at 7fff dot com
I thought I had seen an example of this somewhere in John's sample code, but I can't find it now. I'm fairly sure AWDR gives some examples.
You could pass the observation set id as a parameter in the URL for the form, but my personal interpretation of the requirement not to change the HTML is that we're supposed to use the hidden field in the form, which will make all of the information stay in the POST parameters. There are helper methods for hidden fields.
-- When an observation is added, it must be added TO an observation set. Therefore, when the form that lets you add an observation posts back, there must be some indication of the observation set id to which that observation should be added. Therefore: (a) you may pass the observation_set_id to the form in an instance variable; (b) use a hidden field to capture that id so that it is sent back when the form is posted; (c) in the action to which the form posts, obtain the observation_set_id from the params hash.
-- For time forms in forms: Take a look at the ChildCare Co-Op application. The helper is: datetime_select - it has many options.
Thanks
Think about it this way:
-- You set an instance variable.
-- A form is displayed.
-- The user clicks "submit" or "add observaiton" (whatever's on the button).
-- Now a new controller receives the request (i.e., the "post" of the form)
How does this new controller know what observation_set_id you want?
You have to get that observation_set_id into the params hash.
And how do you do that? Include the observation_set_id in a hidden field.
I haven't experimented with this yet (I'm in the middle of creating a rudimentary two-model Rails app to test it, but my son wants time on the computer before he goes to bed), but if I'm reading the Rails documentation correctly (an iffy proposition at best), then we might be getting the observation set id for free in params[:id] -- the documentation for the options for "form_for" says something about the options being the same as for "url_for" and "link_to", and the doc for ActionController::Base#url_for (http://api.rubyonrails.com/classes/ActionContro...) says,
>>> When generating a new URL, missing values may be filled in from the current request‘s parameters. For example,
>>> url_for :action => ‘some_action‘ will retain the current controller, as expected. This behavior extends to other parameters,
>>> including :controller, :id, and any other parameters that are placed into a Route‘s path. Â The URL helpers such as url_for have a
>>> limited form of memory: when generating a new URL, they can look for missing values in the current request‘s parameters.
>>> Routes attempts to guess when a value should and should not be taken from the defaults.
It's probably better to include the id explicitly when it's desired, both to show the reader of your code that the id is wanted, and to make sure you really get what you want, but it seems as if it's not 100% necessary.
So the data will be posted into params[:observation]
If the id on the URL (i.e., the id for the observation_set) was used for params[:observation][:id] that would clearly be wrong.
Now that I've tested this out, I see that this isn't the case, but I don't really understand it, just from reading api.rubyonrails.com.
However, seeing what does come in the params, I see that having the observation_set_id as a hidden value in the observation form handily puts it in exactly the right place, so that params[:observation] contains exactly what it needs to get passed as the argument to Observation.new.
In any case . . . as you say: "having the observation_set_id as a hidden value in the observation form handily puts it in exactly the right place, so that params[:observation] contains exactly what it needs to get passed as the argument to Observation.new" -- Yes, ahem, that's exactly what I tried to spell out!
greatly simplifies the code for the action, by putting everything
into the hash that gets passed to new().
When I click on one of the observation sets on the list (the "RAW"), this brings me to the observation_set controller,
with an ID parameter for the set. From this, I can set an instance variable, before going to a view that allows me to add
observation for that set.
Hence, I have the obseravation_set_id.
(It seems to be working ????)
Suppose you just can arbitarily jump to a page that add observation, without going through the observation_set page, then, you wouldn't have the observation_set_id.
Am I doing something not right ? It seems to be working ???
So, this means:
-- The controller/action that sets up the form must be: ObservationSetsController#show
-- The form displayed by views/observation_sets/show.html.erb must be "for" the :observation model
-- That form must post back to the :action => :create_observation (on ObservationSetsController)
Are you doing those things?
I also noticed that it only works if I initialized the Observation by new (params[:observation]). If I try :
@observation.observed_= params[:observation][:observed_at]
the date is not set right.
Now, I am stuck with no second. I tried select_second, but that isn't the method I want.
CCC also doesn't have "seconds".
Why don't we get the second field. It fields so "normal" to have the "seconds" field.
It is quite frustrating.
See what happens if you say:
<%= form.datetime_select :observed_at, { :include_seconds => true } %>
This is by analogy to
http://api.rubyonrails.org/classes/ActionView/H...
where there is this comment:
# Creates a time select tag with a seconds field that, when POSTed, will be stored in the entry variables in
# the submission_time attribute.
time_select("entry", "submission_time", :include_seconds => true)
and if you do not check any box (for observations), then, there will be a page telling me that something went wrong.
We are supposed to save the observation set id into the user table. We save off the last observation set the user chooses.
However, I don't see how we use this information.
When I log on, I get to the dashboard, which allows me to:
- logout
- Get a list of metrics (i.e. observation sets)
- Create a new observation set
- Compare
So, I don't see how and where we direct a user to a page with the most recently used observation set.
The assignment reads:
"There are some small changes between this version and the prior version: 20081111021247_add_current_observation_set_id_to_user.rb adds a column to user “current_observation_set_id” - whenever you view an observation set, the id is saved here so that when you log in from a cookie, you can be redirected to that set: This makes it especially easy to enter a new observation for whatever set you were last looking at. "
So, when I log on, assuming that there's a cookie, do we not go to the dashboard, and instead go straight to the page where we can add new observation s?
Thanks
(1) Log in.
(2) close your browser without logging out.
(3) Go back to the application. See where you end up?
If this doesn't work for you, let us know.
Reason for this behavior: There is ONE activity that the user wants to do every day: Post data. If you have ever tracked your weight, you will do anything to avoid this behavior. Therefore, the application makes it as easy as possible.
This will require me to modify my browser settings to accept persistent cookies, won't it?
(But shouldn't it work equally well to leave the browser open and simply close the tab or window that's connected to the metrics mine, and then go back to the application?)
I am not 100% about this, but I think if you close all tabs to a site, and then re-open a tab, your prior session cookie will still be used (which makes sense from many typical end-user cases -- if you accidentally close a tab, you don't want to have to re-log in).
Also, it is worth nothing that Internet Explorer and Firefox work differently with temporary cookies (not your question, but related). You can block a temp cookie on IE, but not, to my knowledge, on FF (though doubtless there is a browser plugin for FF that will do it). Also, if you're a security zealot, IE implements P3P, which is pretty great, though few sites implement it server side (one that does is my old company, h3.com - https://www.h3.com).
Why would we want to limit this convenience feature to people auto-logging-in with a persistent cookie? Isn't the redirection to the current observation set equally (or more) useful to someone who logs in daily from their public library or school's lab, or someone travelling around the world tracking their latitude in Internet cafes? The way I use my own computer, taking me from the home page to the desired observation set is of almost no use at all, first because my browser discards persistent cookies on exit for privacy reasons, and second because for sites that I visit frequently, my bookmarks generally take me not to the home page of a site, but directly to the page I'm interested in (and if those pages require login, most well-designed sites will redirect me to a login page and then from the login send me directly to the page I was trying to get to).
If you logged in at school on a computer where you didn't have a cookie, do you want someone looking over your shoulder to know right away that you've blown your diet?
It is definitely the kind of thing that would get tuned based on user response.
It takes me to the dashboard.
BTW, why do you need o save the information in the database as well as in the cookie ?
I thought that if you save it in the database, then once you look on, you will get the observation set information from the database.
If you save it in the cookie, then you get it from the cookie. Why do we need both ?
Thanks
When you say: "why do you need o save the information in the database as well as in the cookie ?", what do you mean by "the information"?
Also, "the information" is the observation_set id.
I thought we're supposed to save off the last used observation_set id somewhere, so that when the user log on again, he gets send to the page whereby he can add a new observation for the observation set he last used.
Now as an admin
I also noticed that in the reference implementation, the delete also seem to have rows (observationKinds) automatically disappearing.
Also, when I hit destroy for some of the ObservationKind, I to an error page.
I cannot reproduce the "automatic" disappearance of observation kinds, or any error page. If you delete all of the observation kinds (PLEASE DON'T!) you will find that you can't create a new observation set (I think). This was discussed earlier, and we said: "An admin would never delete all of the observation kinds, so we will consider this a feature, not a bug."
I have just reset the database. If you can identify a set of seps that will produce this behavior, from login to the error, e-mail the steps to me.
It delete multiples rows for each delete key I hit.
I hope that you can reproduce this. Perhaps my problem with ObservationKind delete is related or similar.
If you are deleting observations (metrics), you would use the checkbox and then click "delete checked." There is only one button here, so I don't know what you mean by "each delete key I hit."
If you are deleting observation kinds -- "kinds of metrics" in the UI -- you would be clicking the delete link.
Note that when an observation kind is deleted, then the display of the KIND at the top of the "show" page for the observation set can no longer display the kind. So it is blank. There is an instruction regarding this in the static page for the "show" template.
In the reference implementation, the id of the newly-created observation is put into the flash [did you do this?], so that when the list of observations is re-displayed, we can change the background color of the row [Have you figured out how to do this?]. You need to do this, too; to get it to happen you will want to dynamically change the style element on the correct <tr> tag [do you have a way to determine the correct <tr> tag?]. E.g., it would look like:
<tr>
when the row shouldn’t be emphasized; and
<tr style=”background-color: #E0FFFF”>
when it should be emphasized. This is the sort of thing you can glean from view/source for the reference implementation.
---------------------
So this means that when you display the <tr> element for the row, you are going to have some code more or less like this:
<tr <%= if SOMETHING then '' else 'style="background-color: #E0FFFF"' end %>>
The part after the "then" is when the condition holds -- i.e., when it's an ordinary row; the part after the "else" is for when the condition doesn't hold, which would be the case when you want to "decorate" the row. There are other ways to get the effect: You could create an actual style and then select it with the "class" attribute on the tr element.
The "EOFFFF" is from inspecting the rendered HTML of the the reference implementation (after adding an observation).
You have to figure out SOMETHING. It is an expression based on the whatever you put in the flash that indicates the item number of the most-recently-added observation.
-- If there are errors, render. Why? Because you use the instance variables to trigger to the error display.
-- If there are no errors, then you want to redirect so that the user gets a fresh page and a page reload won't re-submit the form.
Other frameworks will redirect for error display, too; the reason Rails doesn't is presumably because it means using the session too much.
"You have a nil object when you didn't expect it!
The error occurred while evaluating nil.has_key?"
I have gone through the book many times, through your Lecture 9 slides, reviewed the "CRUD" application code (which all runs just fine on my machine).
To try and fix this issue, I am working with the admin's Measurements "New Measurement" form, which is the simplest.
The HTML produced on my form is identical to that on metricsmine.plugh.org. So there must be a problem on the "measurement.rb" or "measurements_controller.rb".
The error is being thrown by the following line in the "def Create":
@measurement = Measurement.new(params[:measurement])
If I remove the code that does the create / insert, and just pass the #{params[:measurement]} to the "flash" message on the index page, then the results of that printed variable are:
nameasd
(where I typed "asd" into the name field).
For the above I had not initialized any variables in the "def new" with any variables. If I add
def new
@measurement = Measurement.new
end
to the controller, then I can't even get to the "New Measurement" form at all. Clicking on the "New Measurement" link gives me the error:
wrong number of arguments (0 for 1)
Otherwise, I am progressing, but I've been picking at this one crucial issue for too long now. Please assist. Thank you.
(1) In views/measurements/new.html.erb: What does your "form_for" line look like?
(2)
Double-check that your Measurement model, defined in measurement.rb, looks like this (this is what we handed out with the "solution" for the associations and validations milestone):
class Measurement < ActiveRecord::Base
has_many :units # 7b
has_many :observation_kinds # 6b
validates_presence_of :name
validates_uniqueness_of :name
validates_length_of :name, :maximum => 30
end
(3) Remove your file db/development.sqlite3 and re-run your migrations from scratch. Important: you should be using the model definitions (with its associations and validations) and migrations from the solution download.
2) HOWEVER, I found the following in my measurement.rb. Once I removed it, then everything worked fine.
def initialize(measurement)
@measurement = measurement
@name = name
end
I must have added this when in my "I'll try anything" stage.
3)...
Thank you!
Is there a way to print debug info out to the console or something? I want to see some errors at least, or find out where my mistake is.
You say that you created a CREATE "function" (I assume you mean method?) in a helper object. Action methods should be on the CONTROLLER, not on any helper objects.
So, the upshot is:
(1) In the observation_set.rb file, which defines ObservationSetController, you should define a "create" method. This is the method that allows you to create a set of observations. It will look something like this:
def create
# you add your code here
end
(2) When a specific observation is added, that is handled by a method called create_observation. So in that same file you will need:
def create_observation
# you add your code here
end
In both of these methods, you may find it helpful to add calls to the "puts" method to dump whatever debug code you want to the console.
One last thing: Everything I've said here I said in the assignment description above in the section that starts: "Controller: ObservationSetsController
Notice that this controller manages updates of BOTH ObservationSet and Observation. This is not an unusual pattern. Since Observation is almost completely a “slave” of ObservationSet, it is convenient to manage both Models in the same controller. When we get to REST, we will talk about changing this."
And then I went on to define exactly the methods you need to define. I am not sure what you mean in your post about writing a "dummy function" (there are no functions per se in Ruby) or "the helper object" (since you really shouldn't need to do anything with helpers).
For the final project: A great thing to do is to try to manage URLs so that they aren't sequential numbers. Even if you check the user who supposedly owns a given resource/item, it can be good to not even reveal the fact that something exists at a certain id. To do this, you would add a column and you would set it to some String version of a Hash of unique info for that record; then look up by that added id, rather than by the primary key.
Couldn't find rollup for observation at
Application Trace | Framework Trace | Full Trace
app/models/observation.rb:36:in `before_validation'
app/controllers/observation_sets_controller.rb:53:in `create_observation'
I could not figure out why? Could you guide me?
If "observed_at" is bad, then no row will be found, and that code will fail.
Therefore, double-check that you are setting observed_at is being set properly.
There are only rollups for dates between 2008 and 2010 -- so there could be an issue if you add an observation farther in the future. If you look at the rollups migration, you should be able to figure out how to create more rollup data for more years in the future.
But, generally, you want to store time/date data in UTC.
Also: It is easy to create UTC times . . . you might have noticed in models/rollup.rb, db/migrate/data_add_rollups.rb and elsewhere.
In other words: If you stick to UTC, you don't have to do any conversions.
The submission is like so:
0. Before submitting, verify that the migrations work! I.e., delete (or rename) db/development.sqlite3 and do "rake db:migrate". Check out your app! It can happen that you are relying on bad data being in the database, so exercise your app with a clean slate.
1. There should be a small readme text file in the root of the project with your name, e-mail address, and the name of the project -- this is simply so that if we change the name of your project we can still figure out whose it is!
2. If you are doing anything "unusual" or have bugs that require special discussion, include that discussion in the readme. There is NOT a requirement for a "writeup" for this assignment, because the assignment is essentially about fulfilling a fairly narrow set of requirements. Do include judicious code comments for anything that is unusual, weird, especially superb, etc.
3. You may have a file bin/PKZIPC.exe - remove it. Your ZIP won't go through some e-mail agents with it included.
4. ZIP your project with
rake package
It is possible that this will fail on systems that do not have a working ZIP program -- we have a ZIP in Ruby included, but it can sometimes break on Windows.
If rake package doesn't work, ZIP up your project with any ZIP program. If you have to manually ZIP, remove the files from tmp/ and log/ . INCLUDE YOUR NAME in the name of the ZIP archive.
E-mail it to your TA.
Also, you say we should delete our database and rake db:migrate. Do you want us to package our submission with our test data in the database, or just a clean database, or none at all? Or does this even matter?
The safest thing would be to rename your "good" database. So that way if it turns out that your migrations fail, we can still do some forensics to figure out what's going on.
I need to double-check the Rakefile 'cos it may do something funny with db/
John
For an observation kind I can say something like observation_kind.measurement.name because all the methods are made available to the observation_kind through the measurement relationship.
Should I also be able to use the same relationship with units? For example unit.measurement.name? When I do this from the unit's index view the measurement is nil.
ruby script/console
Unit.find(:all).first.measurement.name
You should be able to do:
Unit.find(:all).each { |u| puts u.measurement.name }
I.e., iterate through all of your units, and see if any break on the following of the measurement association.
One thing you want to watch for is this:
-- If in your own implementation you add an observation at 5:00 PM, it should show up as 5:00 PM in the list.
What is going on here is that times are stored in the database in UTC (universal time). If you made the mistake of entering dates in, say, local time, you could get a discrepancy.
it is unlikely that this is happening to you.
How does this line work? :observation_ids[] isn't something I have seen in my code. Is this meant to gather the observation.id into an array? I gather that the obs.id will send the obs.id to the update method so that an observation can be deleted.
The checkbox technique is also used in ChildCare Co-Op. Please review those materials.
Thanks!
The short answer is that when you put [] after an attribute name, Rails will magically take each check and assign "true" to the array element for the check id.
It's totally non-obvious, which is why I discussed it in lecture, and recommended that people look at the ChildCare Co-Op code.
<form action="/observation_sets/create_observation" method="post">
<input class="text large" id="observation_notes" name="observation[notes]" size="30" type="text" />
<select id="observation_date_1i" name="observation[date(1i)]">
... and all the other (2i), (3i)... fields
</form>
I can grab the "observation[notes]" field (shown above) just fine, but for some reason just keep getting nil values when trying to work with the "observation[date(1i)]" fields.
params[:observation][:notes]
grabs the notes, but
params[:observation][:date]
won't grab any dates... and
params[:observation][:date(3i)]
throws an error.
Played around with
convert_date
to no avail.
This has got to be simpler than I am making it. Probably a one-liner...?
Incidentally, at work we have noticed that there are problems with datetime_select on Rails 2.2.2, so I hope you haven't inadvertently updated your Rails version!
If you continue to have problems, post.
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.1.1/lib/action_view/helpers/form_options_helper.rb:214:in `options_from_collection_for_select'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.1.1/lib/action_view/helpers/form_options_helper.rb:398:in `to_collection_select_tag'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.1.1/lib/action_view/helpers/form_options_helper.rb:133:in `collection_select'
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.1.1/lib/action_view/helpers/form_options_helper.rb:445:in `collection_select'
app/views/observation_kinds/new.html.erb:11:in `_run_erb_47app47views47observation_kinds47new46html46erb'
app/views/observation_kinds/new.html.erb:5:in `_run_erb_47app47views47observation_kinds47new46html46erb'
app/controllers/observation_kinds_controller.rb:33:in `create'
But: to figure out what's happening with parameters, in general, I've found it very useful, when I get totally confused, to stick the line
puts params.inspect
into a controller action, and then go look at the output from my server, to see exactly what it is that the controller is seeing after the user posts the form.
In general you want to construct your forms so you rarely, if ever, need to futz with the parameters, especially in basic CRUD actions.
I'm getting a lot of questions from people having trouble with params. Outputting it with params.inspect, tailing your development log, whatever -- it is important to know what is being passed to your action, and what the structure of the hash looks like, in order to debug effectively.
params[:observation][:observed_at]
as well as
Observation.new(params[:observation][:observed_at])
(ie. the "date" field is renamed in this application to "observed_at")
and it just does not work.
I just keep gettting an error
"Couldn't find rollup for observation at "
The date is not being received at all.
In the error message there is a "Request Parameters" section that shows clearly that the parameters are getting sent across correctly as follows:
{"observation"=>{"observation_set_id"=>"2",
"observed_at(4i)"=>"04",
"observed_at(5i)"=>"31",
"observed_at(6i)"=>"45",
"notes"=>"abc",
"amount"=>"123",
"observed_at(1i)"=>"2008",
"observed_at(2i)"=>"12",
"observed_at(3i)"=>"7"},
"commit"=>"Add"}
I think there may be something wrong with my system's helpers when they are catching and reconstituting the date fragments.
I will send my code to Keith right now.
observation = Observation.new()
observation.observed_at = Time.new(params[:observation][:observed_at])
but why go to the trouble of addressing this level of detail when creating your observation?
You have everything you need in params[:observation] -- the observation_set_id, notes, amount, and all of the pieces of observed_at.
Just invoke Observation.new(params[:observation]), and trust Rails to unpack everything properly for you.
As I said, generally, you want to build your forms so you can do as you described, and mess with parameters only on rare occasions.
Naturally, I've been watching this discussion of datetime_select with some interest.
My main comment for students struggling with datetime_select is to look at example code:
In the ChildCare Co-Op app, app/views/playdates/list.html.erb . . . and app/controllers/playdates_controller.rb (see the "create" action).
As you see there, datetime_select does all of the heavy leifting -- you don't have to dig into the key of the instance object, nor its pieces.
The one additional piece here is that there is an option :include_seconds which is documented for other tags; despite its omission from the docs for datetime_select, it does exist. I sent around an e-mail on this topic awhile back.
Thanks!
My tests complained that a new ObservationKind was created without a :measurement_id value. My ObservationKind model file includes "validates_presence_of :measurement_id".
First, it looks like the validation isn't working. Wha?
Second, I started a new migration, adding ":null => false" as an option to change_column:
change_column :observation_kinds, :measurement_id, :null => false
but the migration failed with the message, -- change_column(:observation_kinds, :measurement_id, {:null=>false})
rake aborted!
undefined method `to_sym' for {:null=>false}:Hash
WHA???
this seems nuts! any suggestions? thanks.
The reason your call to change_column is failing is because you left out the type: See the doc;
change_column(table_name, column_name, type, options = {})
http://api.rubyonrails.org/classes/ActiveRecord...
Also, when an observation is created, the unit should be the same as the preferred unit as the observation set for which it is created. This is specified in the assignment: "An Observation has a Unit. In the initial implementation, all Observations in a particular Observation Set use the Observation Set’s preferred unit. (E.g., if the Observation Set’s preferred unit is Pound, then all Observations are also in Pounds.)" (http://e168f08.plugh.org/assignments/assignment...).
Eventually, it would be nice if one observation could be recorded in pounds, and then later in kilograms, with automatic conversions between units of the same measurement kind.
Also, at present, when you create an observation set, you never pick the unit. You only pick the KIND, and, by specification, "also set the @observation_set’s preferred unit to the first unit of the selected ObservationKind’s Measurement!!" (http://e168f08.plugh.org/assignments/assignment...). Notice that we have not defined here what "first" really means; as long as you set the observation_set's unit to SOME unit that has been associated with the measurement of the picked observation kind, you'll satisfy the requirement. I probably should have said "first in order of create time." In any case, lacking an ability to convert between units of the same measurement, it makes no sense to allow a lot of flexibility with units.
http://metricsmine.plugh.org/observation_sets
We're sorry, but something went wrong.
We've been notified about this issue and we'll take a look at it shortly.
After I run
rake db:migrate VERSION=02
rake db:migrate
and I received the following error message. I am not sure why? What do I need to do?
ActiveRecord::RecordNotFound in WelcomeController#welcome
Couldn't find User with ID=7
RAILS_ROOT: C:/Ruzh/Harvard/CSCI E-168/Assignment3
Application Trace | Framework Trace | Full Trace
C:/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active_record/base.rb:1383:in `find_one'
C:/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active_record/base.rb:1366:in `find_from_ids'
C:/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active_record/base.rb:541:in `find'
app/controllers/application.rb:31:in `authorize'
I thought I was done.. Logged back in to do a final wrap up, and now I'm confused. Do we need to submit migrations? The Paragraph at the top regarding logging in from a cookie, redirecting to measurements page, makes it sound like we might need to change our migrations. I did them for Milestone 1 but haven't touched them and have been using the provided migrations from this site.
Am i right? Were we supposed to do a version 3 of the migrations?
Thank you.
There are no required changes to the migrations as long as you use the ones we handed out after Milestone 1.
Regarding using the cookie to login and to to the last observation set: That is all handled by the filter in the application.rb we originally handed out.
The only thing you have to do his this: "When an observation set is displayed or edited, the current observation set id is copied to the current user’s attribute current_observation_set_id. You must do this as well. This allows the filter on the application controller to bring the user back to the last observation set edited, for easy addition of new data." See above. This has always been in the requirements.
In several posts since the beginning of the course, I have said: Remove that file.