DISQUS

DISQUS Hello! e168f08 is using DISQUS, a powerful comment system, to manage its comments. Learn more.

Community Page

Jump to original thread »
Author

Cooler

Started by xertroyt · 9 months ago

No excerpt available. Jump to website »

162 comments

  • Some alternate Hello World scripts in various languages from around the world:

    Perl - by 'roman':

    print "hello, world" x 10
    (sorry, had to do it)

    BASH - by 'mario':

    #!/bin/bash
    for RRR in `seq 1 10`; do echo "Hello Planet $RRR"; done
  • Python:

    print "Hello, world. " * 10
  • Lecture 2:
    Why the Array#inject example, for inserting only doubled values of even numbers, failed:

    The problem is that "expr1 if expr2" returns the value of expr1 iff expr2 is true, but if expr2 is false, the value of the whole expression is nil, hence the next time through the block, the memo has the value nil. Instead of "; m", a way around this as a more-pure one-liner would be to use the block

    { |m, e| (e % 2 == 0) ? (m << e*2) : m }

    guaranteeing, via the ternary operator, that the expression has the correct value (the accumulated memo) whether or not e is even.
  • Very good. That would also give you the freedom to squeeze in a semi-colon for another purpose, though our "semi-colon exception" is exactly for this usage.
  • Student Locations Google Map

    I'm looking at the shared map, and I can't see the map pin icon . It looks like everyone has 'Edit' access. Is it possible that someone has deleted the map pin icon by mistake, or am I just blind?
    --MC
  • Morris reported that you need to be logged in to Google first. So if you have a GMail account, make sure you're logged in.
  • nope - logged in and I still can't see anything. That's OK - there's enough icons near Harvard Square anyway. --MC
  • Hmm. If you click 'edit' there should be four icons in the upper-left corner of the map itself, in case anyone else is having problems.
  • The book _Advanced_Rails_ , recommended by John for chapter 1 about Metaprogramming, is available online through the Harvard Libraries' subscription to the Safari bookshelf, free to anyone with a Harvard ID and PIN. Just go to http://holliscatalog.harvard.edu/ , search for the book, and click on the "INTERNET LINK". The Flanagan and Matsumoto book _The_Ruby_Programming_Language_ is also available, and, presumably most (all?) other O'Reilly books.
  • In last week's lecture (which I've just finished watching), someone asked whether an eigenclass could have class variables. John said no, but a little experimentation in irb shows that the answer is yes. I'm not sure why you'd want them, but they're there (and, as far as I can tell, should only be available through the eigenclass's methods):

    foo = "I am a string"
    def foo.method1
    @@eigenvariable = 'I am a class variable'
    end
    def foo.method2
    puts @@eigenvariable
    end

    foo.method2
    NameError: uninitialized class variable @@eigenvariable in Object

    foo.method1
    foo.method2
    I am a class variable
  • This is a case of Ruby trying to use the same rules for classes and objects even where they don't make much sense (at least they don't make much sense to me). I guess you could imagine wanting a private namespace for the eigenclass, but . . .
  • I just happen to need to compare 2 files. Actually 2 directory of files.
    So I thought it might be a good opportunities to try doing this with Ruby.

    RDoc says require 'ftools'. Do I just do it with "gem install ftools"?
    Normally how do people get more packages and is it safe to just keep adding packages in ?
    I don't want to mess up my environment for other assignments to come.
    (I am assuming that I have to add ftools in by doing gem install)

    Is there a way to find out what other things we can install.
    I did a gem -list, but I assume that lists something I have installed.


    On a separate question, does something like methodA(self) work ?
    I mean can one pass self as a parameter.

    Thanks
  • ftools isn't a gem, it is part of the standard library:
    http://ruby-doc.org/stdlib/

    require 'ftools' in your script should work fine; you can always check in irb, if you type 'require 'ftools'' and true is returned, you have the library available.

    Also: self is an object, and as such can be passed as a parameter. You would more often see 'yield self' rather than seeing self passed as a method parameter, I think.
  • Thanks.
    Yes, I have ftools.
  • Hi,

    I'm working in Eclipse with an Aptana plugin... Running on Windows and Linux, on two different machines. Sqlite3 works just fine, but I'm trying to use my Derby DB, which is bundled with Elipse for development. I've update the .yml file to point to the jdbc driver required to access the Derby DB, but I'm having a tough time working with Derby. The immediate problem is when I run "ruby script/generate scaffold test_db title:string" I get the following error:

    /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active_record/connection_adapters/abstract/connection_specification.rb:232:in `establish_connection': Please install the jdbc adapter: `gem install activerecord-jdbc-adapter` (no such file to load -- java) (RuntimeError)

    I've installed the activerecord-jdbc-adapter using gem... Not sure what I need to do. I figure it's something really obvious I'm missing. Any help is appreciated.

    Thanks,
    Mike
  • I think that AR-JDBC bridge is for *JRuby*.

    But you are typing:

    ruby script/generate scaffold . . .

    (i.e., ruby.)

    Do you want ruby or jruby?

    I haven't used JRuby with rails, but try

    jruby script/generate scaffold . . .

    Also: This is way outside the scope of the course. If you want a recommendation, I would say: Write your app with the Matz interpreter (e..g, ruby) and then when it's working, try GoldSpike or one of the other strategies to get your app to run inside a JavaEE container.
  • OK... Thanks. No worries. Will continue to fool around with it... Just creating a bunch of sample projects so that I can make sure I understand all of the steps required and how all of the MVC components ( and others) work together. The external DB was part of my experimentation with the yml file.

    Not critical to understand at this moment. Will figure it out eventually.

    Thanks again,
    Mike
  • My gut says: Stop using Eclipse/Aptana right now. Learn Rails with an ordinary text editor.

    At present you are trying to change three things at once: The implementation of Ruby itself (from Ruby to JRuby); the runtime (managed by the IDE); and the database.
  • Wouldn't it be nice if rake spot/test printed the errors in reverse order? Searching up the terminal window for the first error in a long string of tests is a time consuming pain. I wonder if anyone has ever tried printing tests to a file, reversing the paragraph order and then reading the file from the terminal.
  • There are test runners that present a GUI. But at this point, it is best to struggle with the text output. Consider it an incentive to get your code to pass more tests (and reduce the output).
  • Along the same lines: wouldn't it be nice if these comments appeared latest-first?
  • Good idea -- I just switched it.
  • cool!
  • I'm sorry if this was mentioned somewhere and I missed it, but I attempted to mail my ZIP package to Keith at Gmail.com , and they don't take ZIP or TAR.GZ files. I'm including the error message here as evidence. -- MC

    209.85.217.181 failed after I sent the message.
    Remote host said: 552-5.7.0 Our system detected an illegal attachment on your message.
    552-5.7.0 Please visit http://mail.google.com/support/bin/answer.py?an...
    552 5.7.0 to review our attachment guidelines. 6si9929189gxk.79
  • They most certainly do take .ZIP files.

    The error is that you left the PKZIPC.exe file in the bin/ directory.

    I said in e-mail and in posts: remove this file first.

    John
  • have the assignment grades been distributed yet? The email said early thursday morning or wednesday.
  • I asked the TAs last night to e-mail the grades.
  • I keep thinking about the idea of implementing constraints inside the DBMS vs. Rails. Wouldn't people who have more than one kind of program modifying their database benefit from doing constraints inside the DB?
  • Yes, absolutely.

    If you know the syntax for how to add constraints in your database, you can run raw SQL through AR to define those constraints -- I think I give the page number in my slides.

    Which reminds me, I need to post the slides! Will do so tonight (slides are on my laptop, which I don't have with me at work today).
  • Hi,

    If I want to use Ruby/Rails to access an existing DB, and its naming convention for the tables is inconsistent with that of Ruby/Rails (e.g. single/plural), how do I set up the ActiveRecord:Base extension? For example, if a SQLITE3 table is called ABC_123, what does the model class look like?

    Thanks in advance,
    Mike
  • Mike,

    Take a look at p. 296 in the AWDR PDF. You can say "set_table_name" in the Model to bind a model to any table you want.

    John
  • Great! Thanks very much.

    Mike
  • During last week's lecture (lecture #7?), I asked about what gets saved when, if an object is added to a "has_many" collection, e.g.

    class User < ActiveRecord::Base
    has_many :stocks
    end

    class Stock < ActiveRecord::Base
    belongs_to :user
    end

    u = User.new()
    s = Stock.new()
    u.stocks << s

    The question was when does this relationship get written to the database?
    Being somewhat behind in my reading, I just found this in the textbook, in material that should have been read before the lecture. Page 372 of AWDR, the last part of section 18.7 "When Things Get Saved", and the answer is "it depends". If the parent object (in this case, User u) exists in the database, then adding the child object (in this case, stock S) to the parent's collection automatically saves the child (i.e. updates the child's database row). If the parent is NOT yet in the database, then the child object is not saved until the parent is saved.
  • Thanks. Here's a bit of sample code (for migrations2) which demos the case -- followed by the output SQL.

    require File.expand_path('setup')
    newguy = User.new(:email => "neville@example.com", :first_name => "Neville")
    internap = Stock.new(:company => 'Internap', :symbol => 'INAP')
    newguy.save!
    newguy.stocks << internap

    jgnmbair:migrations2 jgn$ ruby demo4.rb
    User Create (0.001168) INSERT INTO "users" ("updated_at", "phone_number", "first_name", "password", "last_name", "email", "created_at") VALUES('2008-11-03 07:03:43', NULL, 'Neville', NULL, NULL, 'neville@example.com', '2008-11-03 07:03:43')
    SQL (0.000460) SELECT "company" FROM "stocks" WHERE ("stocks".company = 'Internap')
    SQL (0.000183) SELECT "symbol" FROM "stocks" WHERE ("stocks".symbol = 'INAP')
    Stock Create (0.000524) INSERT INTO "stocks" ("company", "updated_at", "symbol", "user_id", "created_at") VALUES('Internap', '2008-11-03 07:03:43', 'INAP', 3, '2008-11-03 07:03:43')
  • The partial crud example code, from lecture 9, contains calls to the form_for helper method, where part of the parameter list is

    :url => { :action => :update, :id => @section }

    and when this gets processed by erb, the action URL contains @section.id at the end of it, just as if we had written

    :url => { :action => :update, :id => @section.id }

    except that this works even if @section is nil, omitting the id in that case.

    Playing with this in my own code, I see that this works the way one would like it to, eliminating the exception which would get raised when @section is nil.

    But where is this documented? I can't find it in the on-line Rails documentation, and I suspect that it's somewhere in AWDR, but I can't locate it there either.
  • I can't reproduce that -- maybe I'm misunderstanding the problem. You mean even though @section is nil, when you take @section.id in the view you don't get an exception?

    E.g., if in SectionsController I do this:

    def edit
    @section = nil
    end

    and then in views/sections/edit.html.erb do:

    <% form_for :section, :url => { :action => :update, :id => @section.id } do |form| %>

    I do get the nil exception ( "Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id" )
  • There's nothing to reproduce, and it's not a problem. (Mis?)reading the documentation, I would expect that the :id key would take an id number as its value, so that the code (if @section is not nil) should be
    :url => {:id => @section.id}
    and in fact, this works exactly as I expected. And if @section is nil, then we get the exception, also as expected. No surprises here.

    BUT, we can also just use @section as the value for the :id key, and, as with so much in Rails, magically the right thing happens: apparently, Rails detects that the value is not an integer but instead an ActiveRecord object, and calls its id method (and knows enough NOT to call the id method when its argument is an id number). And if @section is nil (or maybe it's if @section.id is nil), the id number is not added to the end of the URL. This allows us to use the same partial template, _section.html.erb, for edit_with_partial.html.erb, where @section = Section.find(id),
    and for new_with_partial.html.erb, where @section = Section.new (a Section object with a nil id, not, as I thought before thinking it through, nil).

    I don't remember for sure what error I was getting, but I'm pretty sure that the error message said something about a nil. Unfortunately, I can no longer reproduce this error. I was probably mistakenly passing in a nil somewhere where I shouldn't have been, or had a name mismatch, or something else which a more strongly-typed and declarative language would have caught before getting that far.

    But my question remains: for the :id key in the :url hash, we can provide an id number, OR we can provide an object which has an id attribute, and in either case Rails does what we would like. The question is where is this documented? Other than copying your code from the lecture examples, how would I have known that I could use either an ActiveRecord object or an integer here? Where in AWDR or the on-line Rails doc should I be looking, to understand this a little better instead of just treating it like magic?
  • Sure, the use of an AR object without explicitly using the .id attribute is documented in AWDR - see in a bit.

    I'm more concerned about the nil error you were getting -- that's what concerned me.

    In any case, I think this is what you're looking for:

    AWDR, Sec. 20.2 (p. 417 in the latest PDF):

    Create a URL that references this application
    url_for(option => value, ...)
    Creates a URL that references a controller in this application. The options hash supplies
    parameter names and their values that are used to fill in the URL (based on a mapping).
    The parameter values must match any constraints imposed by the mapping that is
    used. Certain parameter names, listed in the Options: section that follows, are reserved
    and are used to fill in the nonpath part of the URL. If you use an Active Record model
    object as a value in url_for (or any related method), that object’s database id will be used.
    The two redirect calls in the following code fragment have an identical ef fect.
    user = User.find_by_name("dave thomas")
    redirect_to(:action => 'delete', :id => user.id)
    # can be written as
    redirect_to(:action => 'delete', :id => user)

    Unfortunately, I don't think it's documented in the RDoc for url_for, routing, or the other places I might expect it.
  • Thanks. What a (relatively) obscure place for it.
    I'm fairly sure that my nil error crept in while I was refactoring my code to use a partial template, and the partial template must have been using some variable that didn't (yet?) have a defined value within the partial.
    Somehow, in the course of fixing the wrong problem, I accidentally fixed the right problem.
  • Well, I'm going to be going into the routing system in tonight's lecture, and will be talking exactly about some of that magic.
  • Hi,

    In the example online, within the show, used to create a new observation, you have the metric kind (which I believe is the observation_kind.name) displayed within the title area.

    But in the static HTML distributed, you have this information appearing outside of the title.

    I'm guessing you meant to have it in the title. But I want to make sure this is not a distinction you made intentionally.

    Thanks,
    Mike
  • When you add an observation here: http://metricsmine.plugh.org/observation_sets/s...

    you should see the name of the observation set in two places:

    (1) In the <title>
    (2) above the form (e.g., Metric: my weight)

    Is that what you mean?

    So, for:

    (1) The <title> bit is set *in the layout*: You have to set the right variable in your template to make this work. This pattern is also used in CCC, LinkWizz, etc.

    (2) should be set with your code.

    Take a look at the welcome.html.erb to see how the title is set -- and then look at the layout.

    John
  • What philadelphia Mike is referring to is that, unlike in most of the static HTML examples, and unlike the on-line reference implementation, the sample static HTML for observations_sets/show has the title just as a plain text above the form, rather than in an <h1> element. I agree with Mike, in that I think this was probably unintentional in the static example.
  • I must not be seeing what you're seeing. Do you mean THIS in the static HTML for show.html.erb ?

    <%# Next line should show metric kind dynamically; if
    # it's null, show nothing.
    %>
    Metric kind: personal weight
  • Yes... the Metric kind: personal weight.

    It appears, in the static code, outside the title area (bracketed by h1's above it).

    And in the online version it does not exist.

    Mike
  • That's different from the title.

    Log in as: john
    Then go here:
    http://metricsmine.plugh.org/observation_sets/s...

    The title is: Metric: calories (raw data)

    This is in two places: In the document's <title> tag, *AND* inside of h1's like so: <h1>Metric: calories (raw data)</h1>

    THEN just a bit before that, we give the METRIC KIND, if known:

    Metric kind: CollegeFund - test1

    What has happened is that after a server restart, someone deleted the observation_kind for that observation_set, so it isn't showing for "my weight," etc.
  • Yes, exactly what Mike said. And in the reference implementation, it's expressed as "Metric: whatever" rather than "Metric kind: whatever", and the contents of the <h1> element matches the page title.
    This (matching <head>/<title> and <h1>) seems more correct than just plain text outside of any HTML tags, and is stylistically consistent with the rest of the site.
  • There are simply no <h1> tags around the indication of the metric kind. It is not intended to be consistent. The only part that is consistent is the main title tag, and the <h1> repetition of what is inside of the title tag. The indication of the "metric kind," i.e., the observation kind for the particular observation set, is EXTRA. The name of the METRIC is prefixed with "Metric:" and the name of the METRIC KIND (i.e., observation kind), if known, is prefixed with "Metric kind:". It is different from the name of the observation set. It's simply a little bit more information about the data in question.

    So: In view/source from the reference implementation (much whitespace removed):

    <title>MetricsMine - Metric: calories (raw data)</title>
    <div id="main">
    <h1>Metric: calories (raw data)</h1>
    <!-- ===== ===== ===== ===== ===== -->
    Metric kind: CollegeFund - test1
    <form action="/observation_sets/create_observation" method="post">

    In the view template stub (the static HTML) for observation_sets/show.html.erb:

    <center>[PARTIALLY DYNAMIC - PLEASE IMPLEMENT!]</center>


    <%# Next line should show metric kind dynamically; if
    # it's null, show nothing.
    %>
    Metric kind: personal weight
    <form action="/observation_sets/create_observation" method="post">

    Remember that the <h1>Metric: calories (raw data)</h1> is not in the view templates -- it's in the layout.
  • Got it. I think your previous explanation was clear. Our confusion
    was arising from the fact that none of the pages being presented by
    the on-line version happened to be showing this particular item. I
    will have to cogitate a bit to figure out under what circumstances
    this item would be non-existent.
  • There is a page where you see it: the "calories" set that someone created.

    What I can going to do is reset the database so you can log in and see it with the "canned" obervation sets.

    The app will be down for a bit, and this may cause havoc with your cookies; you may find that you have to log out, delete your cookies for metricsmine.plugh.org and/or close / reopen your browser.

    When an obsrvation set is created, it is tied to a kind. The idea is that if Morris creates a set called "my weight" and I create a set called "my weight," they might both have the kind "personal weight." So that way our data can be compared: They are both of the same kind.

    However, we allow kinds to be deleted. When this happens, the association from the set to the kind will be null, and there will be nothing to display.
  • OK, guys.

    First, definitely clear your cookies, close your browser, and come back to metricsmine -

    Then log in as "john" - and look at http://metricsmine.plugh.org/observation_sets/s...

    Now do you see it? We show the "kind" for the set, if it is available.
  • If you will PLEASE LOOK AT THE STATIC HTML, you will see that it says:

    <%# Next line should show metric kind dynamically; if
    # it's null, show nothing.
    %>

    IF IT'S NULL, SHOW NOTHING.

    So: If you will log in as admin on the reference implementation, notice that someone has DELETED the original observation kind from which the observation set was created. THEREFORE, the kind is empty. THEREFORE, there is nothing to show. THEREFORE, in the live version, nothing is shown.

    THEREFORE, to help you out, I put in an explicit comment in the static HTML that is telling you to dynamically show the OBSERVATION KIND if it is available.
  • Hey John,

    This is the kind of thing that would be a lot easier to ask in person. Something like, "hey, is this supposed to be there?" With a response like "yup".

    When taking a course at a distance, you can't just point and ask a quick question. You need to spell it all out - in an open forum. Which appears to make questions much "bigger" than they are.

    Thank you for the answer,
    Mike
  • You are right about it being easier in person -- I have taught other subjects on-line (English literature at Ohio State; media studies at the New School in NYC) -- and the distance / computer-mediation produces all kinds of communicative problems. It may be that technical topics like engineering and CS are especially difficult online because of the impedance mismatch between computer and human languages.

    In any case, the discussion started with: "In the example online, within the show, used to create a new observation, you have the metric kind (which I believe is the observation_kind.name) displayed within the title area." So that took us down a tricky path, because the kind is not shown in the title -- only the name of the observation set is shown in the title.
  • AWDR advises not to put "too much" code into views. But how much is too much?

    Suppose I have
    class Model < ActiveRecord::Base
    belongs_to :a
    has_one :b
    has_many :c
    end

    Which is more idiomatically Rails-ish, or more recommended by course staff?


    class ModelController < ApplicationController
    def action
    @model = Model.find(params[:id])
    end
    end

    controllers/model/action.html.erb:
    blah blah <% some code involving @model %>
    <% @model.a %>
    <% @model.b %>
    <% @model.cs.each do |c| %>
    ...
    <% end %>

    --------- OR ----------
    class ModelController < ApplicationController
    def action
    @model = Model.find(params[:id])
    @a = @model.a
    @b = @model.b
    @cs = @model.cs
    end
    end

    controllers/model/action.html.erb:
    blah blah <% some code involving @model %>
    <% @a %>
    <% @b %>
    <% @cs.each do |c| %>
    ...
    <% end %>

    ---------------------------------------------
    Is it okay to expose the model's relationships inside the view, or is it better to hide all of this inside the controller, and have the view just access those related objects as instance variables of their own?
  • This is a great question, and a hard question.

    Three rules of thumb all of which may be ignored in a pinch:

    -- Try not to go follow more than one association from an object in a view. I.e., one dot. You can think of this as a version of the Law of Demeter (http://en.wikipedia.org/wiki/Law_Of_Demeter).

    -- Iterating through collections is fine.

    -- Using if/then/else based on the evaluation of a single variable is fine. Anything more complicated is getting into risk.

    Here is a wonderful statement on how you will, in the long run, find it convenient to push code all the way back to the model:

    http://weblog.jamisbuck.org/2006/10/18/skinny-c...
  • A useful point about partials, which hasn't been mentioned in lecture, and if mentioned in AWDR is not stressed enough, in my opinion:

    While copying code from the CRUD example into my assignment 3 code, I found myself putting a lot of stuff into the :locals hash. Then, accidentally, I discovered (and verified experimentally) that any instance variables that are available to the top-level view are also available to the partials. So one doesn't need to use locals to pass those variables to the partial. This also means that when, for instance, using the _section.html.erb partial from the new and edit views, if the instance variable being set in the controller method is @section, and new or edit is calling <%= render partial => :section %>, inside the partial the same information can be accessed as "@section" or as "section", the difference being that if you actually modify that variable, in one case it's local to the partial and in the other, it affects other things (such as if the higher-level view were doing other stuff using that instance variable after it calls render). This is actually how I tripped over this, because I was getting confused over whether I should use the @ or not, and discovered that my output was identical either way.
  • To my knowledge it is not mentioned in AWDR, though I haven't searched for it.

    It's very interesting that you mention that because while I've been using partials for a long time, I never knew that instance variables were even copied over until (guess what?) I was debugging a partial that was surprising me.

    I think that as a best practice you want to avoid using instance variables in partials because it creates an invisible dependency. If you use :object and :locals it's a bit more explicit. And, as you point out, you run the risk of changing a variable in the template that is calling the partial.

    A nice feature to add to Rails would be a mechanism where the partial could say that it "requires" certain locals and/or instance variables.
  • FYI: David Black's "Rails Routing" book, mentioned in this week's lecture, is available on-line (on Safari), FREE through the Harvard library system to anyone with a Harvard ID.

    http://nrs.harvard.edu/urn-3:hul.ebookbatch.SAF...
  • Excellent, thanks for reminding everyone of this.
  • Speaking of routing, any time you change your 'routes.rb' file, *restart your mongrel server.*

    Otherwise you may get "Only get, head, post, put, and delete requests are allowed. Ruby on Rails error".

    Silly me for not going straight to Google on this one. I kept thinking I had screwed-up the code. I found the solution here: http://tinyurl.com/6a8ff5
  • Still a little lost (like me)? http://www.learningrails.com offers nice step-by-step screencasts on app-building basics.
  • Those videos look good. Remember, though, that the "last word" is the AWDR book. Also when watching the videos, be cautious about anything that might mention Rails 2.2 (just released). We're on 2.1.1.
  • John:

    At one point, you used a button in your GUI file window that brought up Terminal already cd'd to that particular directory. What was that? My wrists hurt.
  • On Windows, you want "Open Command Window Here" from this page: http://www.microsoft.com/windowsxp/downloads/po...

    On the Mac, you want "Open Terminal here": http://www.entropy.ch/software/applescript/
  • Fantastic. It works! Thx.
  • The documentation for methods in ActionView::Helpers subclasses (e.g. FormHelper, DateHelper) shows a first argument for each method, which is an object_name. But in the examples, and in practice, that argument seems to be optional, and defaults to the object which is the first argument of the enclosing form_for method. E.g. the signature for datetime_select is

    datetime_select(object_name, method, options = {}, html_options = {})

    but in practice we call it as something like

    form.datetime_select :observed_at

    with the implicit @observation (or :observation) as the object, and :observed_at as the method on that object.

    Two questions:

    1) How does this work, from a language viewpoint? Do these methods examine the types of their arguments, figure out that the first argument is the name or symbol of a method rather than an instance variable, and adjust the argument list appropriately?

    2) More importantly, other than by reading AWDR and intuiting the methods' behavior from the code examples, how would we be able to figure out that some arguments (not the trailing arguments, and not those shown with default values in the method signature via an '=' character) are optional?
  • 1) When you call form.datetime_select, the form already knows what object is in play (because you said form_for, which yields the form variable). So it can delegate directly to the datetime_select which expects an object as the first param. I haven't looked at the source, but that is likely how it is implemented.

    2) The on-line documentation is bad, in my humble opinion, because it underplays what the "form builder" (the variable form_for yields). The docs (http://api.rubyonrails.org/classes/ActionView/H...) say:

    The generic way to call form_for yields a form builder around a model . . . (and they quote an example) . . .

    There, the first argument is a symbol or string with the name of the object the form is about, and also the name of the instance variable the object is stored in.

    [KEY SENTENCE -->] The form builder acts as a regular form helper that somehow carries the model. Thus, the idea is that

    <%= f.text_field :first_name %>

    gets expanded to

    <%= text_field :person, :first_name %>

    -----

    And that is the whole enchilada. You can use any of the form helpers via that "f" or "form" or whatever variable you have assigned to the one yielded to you by form_for.

    The RDoc generator that makes the HTML pages should cross-reference what is happening here so that whenever you're looking at "datetime_select" there is some indicator of how you would use it from form_for; and the idea that the variable form_for yields magically sprouts these methods that delegate can't be overplayed enough.
  • Even worse, in the on-line doc:
    I just inserted a line in one of my views, inside the form_for block, that says

    f is a <%= f.type %>
    (where f is my block parameter), and it tells me, "f is a ActionView::Helpers::FormBuilder", but api.rubyonrails.com doesn't have ANY DOCUMENTATION for the FormBuilder class. So your idea of cross-referencing FormHelper#text_field, etc., is a good idea, but there's NOTHING TO CROSS-REFERENCE.

    (and, to add to the list of complaints: instead of just ranting about this here, I went over to rubyonrails.com to report this gap in the documentation, like a good citizen, and I can't find any easy way to report documentation bugs. I'm not feeling sufficiently motivated to create an account and log in, just to inject a documentation complaint into the on-line Rails bug-tracking system.)

  • After watching this week's lecture this morning, and checking quickly in the Rails documentation, I wonder why there's a helper for Atom feeds, but no helper for RSS. It seems to me that I see lots more RSS feeds on the net than Atom feeds.

    A very quick web search reveals this article

    http://myersds.com/notebook/2006/05/11/how_to_g...

    which seems very clear, which is just using generic Builder to put together the XML for an RSS document, which raises the next question, whether AtomFeedBuilder is providing any real added value, compared to just building an Atom feed out of raw XML
  • Atom is a building block for providing much more sophisticated feeds.

    This is a biased account, but will give you some of the flavor for why you might go for Atom:

    http://www.intertwingly.net/wiki/pie/Rss20AndAt...

    This is a big deal: http://www.intertwingly.net/wiki/pie/Rss20AndAt...

    Re: building an Atom feed out of raw XML: If you use the atom_feed helper, then if common usage moves to a different version of Atom, you'll have built your feed using a higher level API, which might get updated -- and then you don't have to dig around in your own home-build XML.

    There is nothing wrong with providing both kinds of feeds. "One resource, many representations." If you include two "auto discovery" links, must feed consumers will give you an option to select (atom vs rss 2.0, etc.).
  • Which still leaves the question of why the developer(s?) of Rails included a helper for Atom in the Rails core classes, but chose not to do the same for RSS. The same issue, of common usage moving to a different version, applies.
  • Well, one reason might be that there isn't much of a standard for RSS: http://en.wikipedia.org/wiki/Rss#Variants

    If you want to support RSS, which one? Should you expose 0.9 AND 1.0 AND 2.0? Do we need to support ALL of those? There is doubtless a plugin that will do all of that for you; I would bet that DHH would say that Rails, being "opinionated software" advocates Atom . . .
  • Hi there,

    I'm thinking about the final project, and as one of the elements, I'm interested in maintaining minute by minute usage data associated with internet enabled equipment. But I'd like to roll the data up into hours, days, weeks, and years, so that I will not have to maintain hundreds of thousands of rows for each user for each year.

    Is there a best practices way of doing this? I've been thinking about writing it myself using after_save callbacks on a Usage table. But, it's not all together trivial due, amongst other things, to some recursion issues I foresee (I foresee, I foresee, I foresee :-). I'd be very happy to find out someone has already figured this out and has written a gem or plugin...

    Thanks,
    Mike
  • What you want to do is collect all of the observations, and then periodically have a process that summarizes the data. Or, if you wanted to do it on the fly -- that's fine, too. But i think you are going to have to hand-roll this process. This is very much like data-warehousing ETL (extract / transform / load).

    The original collection could be into a flat file or into a database table (you would truncate or archive the original data after you summarize it). You would surely want to archive it.

    The standard way to manage rollups is with a table such as the one used in MetricsMine. You are free to use it. Note that that table doesn't have indices. You would want to keep your data in a database such as Postgresql or MySQL which does allow for indexes.

    In any case, the big question for you will be what you want to do with the immediately-collected data before it gets summarized. Will users want to see their data trickle in within the hour?
  • They will want to see minute by minute data for the previous 60 minutes. Then hourly averages for the previous day. The daily for the previous 7 days. Then weekly (forever?).

    The difficulty is the missing data... machines go down and so do internet connections. Therefore, the data will have missing elements, which in some cases will span hours, days or weeks. So, I need to be able to handle missing observations as well.

    I'll take another look at the rollups in MetricsMine. I may be able to use some or all of it for this purpose.

    Thanks,
    Mike
  • After reading your comment and thinking about it some more, maybe the best way to handle this is to write to the DB for each event with a timestamp and then report based upon this information. Every week a cron job would run and create weekly average. In that way, the max rows in the table would be 10,800 per user per reporting device. That's not too bad, as long as they are indexed. Most of the reporting will pull the most recent record (greatest timestamp) and will not require a lot of overhead (if it is indexed).

    Thanks,
    Mike
  • That sounds good to me. I think a real question is going to be granularity of the initial data, and the smallest size of the initial report. You would have a significant boost if you could make that initial report by even 10-minute intervals.
  • The way to handle missing data is definitely with a rollup table where you use the rollup to "left join" against your data. The 2nd key technique is to put a key in your "data" table that links to the rollups table (this is what happens in MetricsMine -- when an observation is added, a callback is used to grab the right rollup). The naive approach is to have the linkage between the data table and the rollups data to be by the actual time column, but this is not a good practice.
  • I have a question on 1-to-xxx relation that wasn't clear to me.

    If say ModelB has a field that belongs_to :ModelA, must ModelA has a matching has_xxx field ?
    There is a "has_one" and a "has_many". My situation is has_zero_or_one, and I am not
    clear whether has_one means EXACTLY one, though has_many seems to cover the case of 0 to many.

    To repeat myself, just to be clear, say ModelA has fieldA, fieldB, fieldC. fieldB references modelB.
    There are modelB that does not reference any modelA. What relationship should this be ?

    Thanks
  • Let me say it a bit differently. Let us start with:

    ModelB belongs_to :model_a

    In Rails, this means that the table underlying ModelB (model_bs) should have a foreign key called model_a_id. That is, a row in model_bs "refers" to a row in the model_as table. In other words, the column model_a_id is a foreign key. ModelB is a "child" of the "parent" ModelA.

    The table model_as does not have a foreign key.

    When we define ModelA, we can say in our association that it:

    has_one :model_b

    OR

    has_many :model_bs

    In the first case, there should be 0 or 1 rows in model_b. In the second case, 0 or more.

    The reason you are having trouble with this is in your last paragraph. You write: "Say ModelA has fieldA, fieldB, fieldC. fieldB references ModelB." But that's not how it works. The foreign key is in the CHILD. The parent model DOES NOT HAVE A FIELD that refers to the child. The only way we can "trace" the relationship between ModelA and ModelB is through the *association* -- the *association* (namely, has_one :model_b or has_many :model_bs) is not about FIELDS. It's about a method that allows you to collect up all of the model_bs.

    Finally, something to think about is whether ModelB (whose underlying table model_bs has the foreign key model_a_id) is allowed to have a null for the value of the foreign key. This is something you would have to decide for your own application.

    I think what I've just written is correct though with names like "ModelA" and "ModelB" I might have gotten something backwards. This is why in the examples I've tried to show somewhat plausible model names like "Book" and "IndexEntry" so that there are some semantics to provide cues as to what is the parent and what is the child.
  • Ah, I got the ModelB and ModelA mixed up in my 2nd paragraph, but what you described in your first 10 lines is what I was thinking.

    So, now, I know that
    - "has_one" includes the case of ZERO as well,
    - NULL is allowed for the value of the foreign key

    Thanks
  • Yes, but make sure that you understand: The fact that the foreign key can be null has nothing to do with has_one vs. has_many.

    Let's say that model_a is for people, and model_b is for their company: And we say that ModelA has_one :model_b (so a person has 0 or 1 companies - this is not necessarily the way the real world works, but it's how we're going to do it).

    Example:

    Rows in model_a (columns are: id, name):

    1 John
    2 Bill Gates
    3 Steve Jobs

    Rows in model_b (columns are: id, model_a_id, company_name):

    1 1 digital_advisor.com
    2 3 apple
    3 2 microsoft
    4 null ibm
    5 null dell
    6 3 apple
    7 1 beatthat.com

    NOTICE the following facts:

    (1) Even though our association says ModelA :has_one :model_b, it happens that there are TWO rows in model_b where the foreign key is "1" (for John). That is because having just one is not enforced at the database level with more work. I believe Rails will try to enforce the 0 or 1, but if someone forced that row into your table manually, Rails would just bring back one row from model_b when you follow the association from ModelA.

    (2) The rows in model_b with nulls for the foreign key value are essentially "orphans." They don't know to whom they belong.

    Both of these situations (1) and (2) are problematic. If you want to control whether a null is allows in the foreign key in model_b, look at the ":null" option for columns in the documentation-- in AWDR on p. 277. :null seems not to be in the index.
  • Thanks.

    What I try to model is slightly different.

    Let's say we want to buy something (a house, perhaps).
    You make an "offer".
    If all goes well, this "offer" results in a "transaction".

    So in my case, the "transaction"(modelB) if one materializes, belongs to an "offer" (modelA)
    An "offer" on the other hand, may or may not result in ONE transaction. If no one buys the house, the "offer" will not have a corresponding.
    The "transaction" will never have null value for its foreign key because it is result of an "offer" made.
    So, I think that I won't be running into the problematic situation (2) for this case.

    Thanks
  • Ran across an interesting talk about memcached here: http://www.facebook.com/note.php?note_id=393913...

    This gets a bit in-depth, but it is a description of how Facebook is making use of, and modifying, memcached and the considerations in scaling Web 2.0 applications. There seem to be a lot of people out there using ROR to build applications for Facebook.
  • We "memcache" everything at our company -- including our FB app.
  • The Ajax examples we've seen in lecture, section, and in AWDR, all involve the controller sending text to be injected directly into the page, either something to go directly into the innerHTML of some element, or RJS sending raw JavaScript to be executed by the browser. This all feels to me like it's skating very close to the boundaries between the View and the Controller in the MVC pattern, although I see that it's not, as long as the controller is well-behaved and only does things like rendering partials or other things in the view directory.

    But this all looks mostly like "AJ" without the "AX". The "standard" way of doing Ajax (or at least the style that I'm used to) involves the server sending DATA (usually structured in some form, hence "And XML") to the browser, to be processed by client-side JavaScript. AWDR mentions the possibility of this in passing, but shows no examples. Can we see some examples of Asynchronous JavaScript AND XML (or AND JSON)? How does the code in the view deal with parsing and/or evaluating JSON or XML returned by the server? For the Ajax-worthy bits of my final project, I can't easily see any way that the view would know which elements of the page to update, without embedding code that more properly belongs in the controller.
  • If you use a partial, then the display piece is properly in a view component. I show using a partial in the lecture (the refactoring sequence).

    Also, about the target id:

    Understand that you are clicking on something (triggering a browser event). So, you write view handler code to catch that event, trigger a controller call, and then take the result and shoot it into an element (or its innerhtml) with that id. So the actually move from event to target is all handled in the view, probably where it should be. Indeed, if the controller picked the id, that would strike me as problematic.

    You can send JSON (easily) but I believe that if you want to respond to it in your JavaScript, you are going to have to write that JavaScript manually. Let me check with someone here at the office.
  • You've got to write your own javascript...
  • ta
  • This would by specifying :complete, :success, and/or :failure callbacks in the invocation of link_to_remote? That's what it looks like in the API doc. Are there any Rails hooks/helpers into Prototype, to keep this JavaScript from being totally raw JS?
  • (I replied to this via the Disqus email reply facility, but it doesn't seem to have shown up; apologies for duplication if and when that reply gets here)

    I see that when using a partial, the distinction between the View and the Controller is being maintained, but at one stage of your first lecture example, the controller is just rendering text to be inserted into the innerHTML of a DOM element, and it seems that it could be very easy and tempting to start rendering actual HTML markup in the controller (or, as in the case of echo_observer1, rendering as text any HTML markup that might be in the user input; a quick browse of the the Rails API and AWDR doesn't show me the usable-by-controllers version of ERB::util#html_escape).

    Regarding the element id. In some cases, it's not always trivial to determine which DOM element should be updated after an Ajax call completes. The element could be different for success or failure, or the result could be dependent on information in a form on the page, which needs to be processed to determine which element (if any) to update. My real-world example here is what I'm thinking about for my FP, where there will be a datetime_select which should be processed to determine which <td> in a calendrical table should be modified. I don't think a view should be doing this kind of processing, but the controller can send back structured information which enables JavaScript embedded in the view to compute the element id.

    Other examples of when one would want to process the reply, instead of simply replacing the innerHTML of an element, would perhaps be when the contents are large and unchanged, and one just wants to modify attributes of that element, e.g. style.
  • "a quick browse of the the Rails API and AWDR doesn't show me the usable-by-controllers version of ERB::util#html_escape".

    Duh. That's because it's part of core (non-Rails) Ruby. Improved code for echo_controller:

    def echo_observer1
    render :text => CGI.escapeHTML(params[:echo_observer_text])
    end

    and, correspondingly, in the views, (echo1.html.erb and the partial view _echo_text.html.erb), there should be an 'h':
    <span style="color: red"><%=h echo_text %></span>
  • But why not use a partial for the render (and thus preserve the MVC distinction) and then you don't have to escape HTML, etc. (?)
  • Well, of course you still need to escape the HTML, in the view.
    I agree that using a partial is better, because it preserves the VC distinction. I was commenting on the intermediate stage in the lecture ajax-refactorying example, where the echo_observer1 action renders text directly. This is a good argument against rendering text.
  • It depends on the text!
  • I feel like we're going around in circles here. What it boils down to, I think, is that you're either rendering a partial, thus clearly preserving the MVC distinctions; rendering structured data of some sort (e.g. XML or JSON), following the classic Ajax pattern; or rendering text, which is either plain text (which you'd better escape) or HTML (which steps across the distinction between the controller and the view).
  • Yes.

    I think the best practices are:

    -- Single update of a block of HTML: Use a partial
    -- Single data item, numeric or short String: Possibly render text; probably better to just go with a partial
    -- Update multiple parts of the page: Use RJS
    -- Supply JSON or XML data to Prototype: Render JSON or XML (for XML, possbility use builder)
    -- "Catch" JSON or XML . . . You're on your own. If you use Prototype, at least the methods are based on Ruby iterators.

    The gap is that Rails is good at marshallng data back in XML or JSON, but doesn't give you much in terms of "catching" that data in the view and doing something with it.

    The Rails answer for "how can I update multiple parts of the page" is: Use RJS.

    Incidentally, what is your use case where you want to send data back to the client?
  • > The Rails answer for "how can I update multiple parts of the page" is: Use RJS.

    This still feels gross to me, as if it's violating not only the View/Controller distinction, but also the Client/Server distinction. I realize this is probably unreasonable, but the idea of shipping executable code to the client just feels spooky and icky.

    >Incidentally, what is your use case where you want to send data back to the client?

    Adding an event to a calendar, with a simple "add an event" form on the same page as the table holding the calendar. I don't want to re-render the whole calendar, just the one (at most) <td> that represents the date of the event (if that date is within the currently-displayed date range)
  • The controller picks the view; the view renders something for the client. The data the RJS template reacts to is supplied by the controller; the RJS template shouldn't be going back to the database on its own.

    Also, since the KIND of executable code exercised on the client is primarily about updating the view, it's arguably still within the responsibility of the view.

    If client-side JavaScript is shipped data (via JSON) and updates the view asynchronously, if you're an MVC purist then you have to be very careful to separate your concerns there as well. So I think really that RJS constrains you in a nice way.

    For the calendar:

    -- If the calendar is displayed in a table, you might as well re-render the entire table, because dynamic table cell updating is uneven across browsers, even with Prototype. I think there's a callout somewhere in AWDR that discusses this a bit.

    -- If the calendar is a list of dates and events: If you display the calendar as a list (ul and li tags), then you can update ":before" or ":after" something, and you should be able to squeeze a new item in at the start or end of the list. Having it update in place (i.e., a new event in between two other events) would require you to have a unique id for each list item.

    In any case, get it working without Ajax first.

    Side issue for anyone who is reading: Incidentally, last night after the panel, Amy told me that I overstressed backwards compatibility / graceful degradation. If you are using an Ajax-only component -- such as Google Maps -- then you certainly don't have to render all of the information in the map when JavaScript is turned off.
  • H there,

    I'm working on some test capabilities for the final project. I want to be able to run a server which will inject messages using HTTP to my WEBrick web service.

    I've created a script which will do this. I can make it run as long as I do not attempt to access any User Defined Classes, for example Classes in my app/models directory.

    I've tried to include the environment by using:

    require File.dirname(__FILE__) + '/../config/boot'

    which is apparently how the script/console and other scripts pull in the Environment variables. The script does not recognize my model classes. If I require them in my script explicitly, I can see them, but if they refer to additional classes (maintained in the lib library), Ruby complains about not being able to find them.

    Is there any way to make this work? Please let me know if you need me to provide more information.

    Mike
  • You just want to make requests to your web service? I.e., hit URLs like:

    http://localhost:3000/users/1

    and the like?
  • Sort of...

    I have an XML file I read in to pull some specifics about the User and the site to be tested.

    I set up a log file to ouput status.

    I've created 500 or so components in the DB I need to update through HTTP POSTS.

    I've been using: res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) } to do so, from within a Windows Service I built.

    In the Windows Service, I don't need access to the local classes... I'm just pulling a small amount of information from the XML file and from the local PC.

    In the case of the test, I wanted to pull the specific endpoint information from the System Under Test. I can get at the classes to pull information, but one of the ones I need to access implements "acts_as_mappable". This is a class located within the lib/geo_kit directory. Unfortunately, I can't seem to be able to get the script to see this file.

    My next step is to comment out the acts_as_mappable, in my locations model, to see if I can make it work...


    Here's the script so far:

    require File.dirname(__FILE__) + '/../config/boot'
    require 'rubygems'
    require 'activerecord'
    require 'xmlrpc/client'
    require 'win32/daemon'
    require 'net/http'
    require 'uri'
    require "rexml/document"
    require 'user'
    mappable_path = '../lib/geo_kit/acts_as_mappable'
    require 'location'
    require File.dirname(mappable_path)

    LOG_FILE = File.dirname(__FILE__) + '/test.log'

    #here we want to read in the xml config file
    @doc = REXML::Document.new File.new("./config/test_config.xml")

    #open the log file
    File.open(LOG_FILE, 'a+'){ |f|
    f.puts @doc
    }
    #establish the xml doc root
    root = @doc.root
    #grab the user name & pwd for the test
    @user_name = root.elements[1].elements["user_name"].text
    @pwd = root.elements[1].elements["pwd"].text
    @remote_server = root.elements[4].elements["remote_server"].text
    # Initialize ActiveRecord
    config = YAML.load_file('./config/database.yml')

    #grab the development configuration
    spec = HashWithIndifferentAccess.new(config['development'])
    # Uncomment the next two lines if you want to see the SQL
    # ActiveRecord::Base.logger = Logger.new $stderr
    # ActiveRecord::Base.colorize_logging = false
    ActiveRecord::Base.establish_connection(spec)

    msg = 'Testing script started at: ' + Time.now.to_s
    File.open(LOG_FILE, 'a+'){ |f|
    f.puts msg
    }

    url = URI.parse(@remote_server + '/svc/post_kw_reading/')
    req = Net::HTTP::Post.new(url.path)
    req.basic_auth @user_name, @pwd
    #find the locations for the user from the config file
    locations = User.find_by_login(@user_name).locations
    #create an array to hold devices
    devices = Array.new
    #add the devices for the user to the array
    locations.each {|l|devices.push location.devices}


    #start the while loop which will send usage data to the web server
    #appearing as actual clients
    while true

    for device in devices

    #make up some kw and voltage readings
    kw = rand(10)
    volts = 119.5 + rand

    req.set_form_data({:kw => kw, :volts=>Vrms, :guid=>device.guid,:cost=>'0.22'} )

    res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }

    case res
    when Net::HTTPSuccess, Net::HTTPRedirection
    File.open(LOG_FILE, 'a+'){ |f| f.puts res }
    else
    File.open(LOG_FILE, 'a+'){ |f| f.puts 'Error in posting' }
    end
    sleep 60
    end

    end
  • Put that script into a class in the lib directory, and define a class method called, e.g., run. e.g.,

    class Exerciser
    def self.run
    # YOUR SCRIPT HERE
    end
    end

    Now from the root you can do

    script/runner "Exerciser.run"

    (Check script/runner in AWDR)
  • P.S. Once you do this, you can get at all of your models, everything.
  • :-)

    Works like a champ without the requires!

    Thanks!!!
    Mike
  • Yes... I will try that. I have it working in after commenting out two included libraries I had used in a couple of the models. These were:
    acts_as_mappable and uuidtools. Neither of these are required for my current testing. They are used for adding devices and locations.

    So.... will use your idea right now... and let you know how it goes.

    Thanks!
    Mike
  • If you do it the script/runner way, you should be able to remove ALL of those requires, etc.
  • Hi -- I'm playing with a model, "Sequence", that should have no existence independent of its collection of objects. Validation is tricky here because the model, Sequence, has no attribute that correlates with its collection. It has a has_many :through relationship to "Asana". I don't want to allow any new Sequences to be created without at least one asana associated with them. How would one validate such a thing? Thanks!
  • Could you write out the model names and give all of the associations? E.g.,

    Sequence: has_many :somethings
    Sequence: has_many :asanas, :through :somethings

    That kind of thing.
  • Sure.

    AsanasSequences is the join table. I implemented acts_as_list so that users could rearrange the order of postures in their sequences. The actual name of the association I want to validate in Sequence.rb is "postures", and each of these is an instance of AsanasSequences that relates to one of the asanas.

    To access the properties of an asana in a Sequence named sequence1 you need to use sequence1.posture.asana.

    Here is the class def for Sequence:
    class Sequence < ActiveRecord::Base
    belongs_to :user
    has_many :postures, :class_name => "AsanasSequences", :order => :position
    has_many :asanas, :through => :asanas_sequences
    end

    thanks!
    catherine
  • I think first of all you want:

    class Sequence . . .
    has_many :postures, :class_name => 'AsanasSequences', :order => :position
    has_many :asanas, :through :postures

    The value of :through is the name of the ASSOCIATION through which you have many. So here it should be :postures. Maybe it works with :asanas_sequences.

    Now that I see this model: Are you sure you want to disallow a Sequence with no asanas? Why?

    Suppose in my UI I want to create a sequence named "foobar" and then add a bunch of postures -- Right after I create the sequence there would be no associated postures. So it seems to me that it would not be wrong ot allow the collection to be empty.
  • thanks, John! Makes sense. It does beg the question of how to validate a model for associated instances, but I clearly don't need to use that at this point. Merry Chanukah/Happy Xmas
  • On the "belongs_to" side, you can validate for the key having a value.

    E.g., if a Book belongs_to :user , you would check user_id to be non-null. You can also set that in the migration so AR will enforce it there.
  • Hi,
    How can I add a standalone class to RoR ? I have some source code which I wrote, it works perfectly as a script, there is a class called "IMDB" which, you guessed it, scrapes IMDB for content. I run it from the command line or with a wrapper, but want to get it into my rails site. Where do the files go, and how do you "require" them in the right place?

    (I'm a C++ developer and can't believe that ruby would have an obvious solution to this too)
  • Put in the lib/ directory -- it will be loaded automatically.
  • duh ... should have known
  • Can you write multiple routing statements about the same model?, eg
    map.resources :sequences
    map.resources :sequences, :member => { :get_postures => :get }
    map.resources :sequences, :has_many=>:user_observations
  • that was a really stupid question and I tried to delete it but no go. No wonder Anne wanted to start a separate google group! I couldn't figure it out until I realized that once you post a comment here, it's impossible to delete it. Now everyone knows I'm a schmo.
  • The more stupid questions, the merrier -- especially if you then answer your own question!!
  • Heres's a way to easily pick out syntax errors in your code: Go to http://blog.hungrymachine.com/2008/06/04/rake-t..., and copy the code to a new file in lib/tasks. Name the file check.rake or something ending in .rake. I surrounded the code in a 'namespace :check do' block (after the require statements) so I can just run rake check:check_syntax from the command line and it checks all my code for syntax! It's beautiful.
  • So I've discovered what seems to be a pretty serious gotcha:

    If we have the following model:

    class User < ActiveRecord::Base
    belongs_to :clinic

    we can say things like:
    validates_presence_of :clinic

    but we can't say:
    validates_uniqueness_of :login, :scope => :clinic

    instead we have to say
    validates_uniqueness_of :login, :scope => :clinic_id

    since the "belongs_to :clinic" in the migration for the user model creates a column called "clinic_id" not "clinic".

    This seemed very counter-intuitive, and took me a number of hours to debug so I thought I would post for others.
  • OK, but this will say you can have two users with the same logins but associated with different clinics. Is that ok?

    I.e., 'john' for clinic #1, 'john' for clinic #2.
  • Yup. That's exactly the intent. :-)
  • I am SO CONFUSED! ARRRGGGGh!

    My Sequence form is the most complicated. In a single region I need to have:
    one form that just wants to collect preferences (pose type and pose subtype) so the app can narrow what's listed in the next section. If the user selects either type or subtype the next section will list only the poses that are children of that type/subtype. If the user selects both type & subtype the list will include only poses in both sets (overlapping). I want to do something like <% form_tag {:action =>"accept_asana_categories_and_return_asanas", :id => @asana_type } do %>.. but instead of choosing just @asana_type I want to return either/both asana_type and asana_subtype as parameters to "accept_asana_categories_and_return_asanas".

    Any ideas as to how to accomplish that?

    The next form needs to list a collection of asanas based on the first form's returned parameters, types/subtypes; each pose is a link that will create a new row in the join table, asanas_sequences. Ultimately when Ajax comes in (I haven't even been able to think about Ajax yet!) the list of poses will update automatically.
  • In order to get done (as a friend of mine said in her speech for her graduating class, being done means being "sufficiently cooked"), can you eliminate the pose subtype?

    Then it might be a lot simpler.
  • Hi there! Busy at work here. Things are rolling along. Lots of heavy lifting, but gradually getting there.

    Quick comment on setting up the external site. My Ubuntu server on slice did not come with 'make'. I used "sudo apt-get install build-essential" to install the gnu compiler, after which all worked well.

    I may have missed a step in the tutorial. Perhaps this will help a classmate.

    Take care,
    Mike
  • OK.. spoke too soon. Mongrel installed by sqlite3-ruby complains about " No rule to make target `ruby.h'".

    Googling now.

    Mike
  • I found that if I first get the sqlite3 lib with " sudo apt-get install libsqlite3-dev", then the "sudo gem install sqlite3-ruby" works fine.

    Mike
  • All these geniuses like Philadelphia ready to deploy already, and me still struggling to get through my darn multiple model forms, ain't even touched ajax yet... Are there any more schmo's out there? Please, normal dufuses, tell me you're alive!
  • Amy set me straight in about 10 minutes. ps. please don't take me seriously; I was joking around. In the words of steve martin: soooooorry!
  • I'm having a problem where my application needs to update around 3000 rows , and it's doing it slowly. Any ideas to speed things up? I've removed the updated_at timestamp, which helps a little, but it still takes 5 to 10 seconds. I looked at update_all but there's no pattern that the updates follow. The update SQL command the server prints out say it's updating two integers where id = the id
  • You need to paste in your code.
  • I collected the Word table rows in an array, and wrote them out like this:
    save_these_words.each { |each| each.save }

    I read Time.now before that statement and again aftewards, and it confirms that this is the major bottleneck. (The value is 6.8 seconds)

    In the ouput of script/server there are a bunch of these lines:
    UPDATE "words" SET "current_index" = 816, "current_position" = 19239 WHERE "id" = 2166

    A bunch print out at once, there's a pause, then another bunch, etc, for around 5 seconds, for roughly a thousand rows from id=1300 to id=2300. There is a lot of hard disk activity too.
  • Forgot to mention, the Word table in question has a text column, 4 integer columns, and a creation timestamp column, if that informatoin is helpful
  • George -- I wrote a little simulation app like yours (similar columns) that updates 3000 rows.

    The total time to update 3000 rows, row by row, in Sqlite3, is: 60 seconds.

    I also tried it on MySQL: 47 seconds.

    You are updating each row separately. 3000 / 60 is 50, so you're updating 50 rows per second.

    I don't know enough about your application to know what to recommend. What does your application do? Does this need to happen very frequently? Or can it happen once a night or once per hour? If the answer is "Yes," then you should run this update code periodically with a scheduled task or cron job.

    Does the data need to be access immediately after it is updated? If the answer is "no," you could update the data asynchronously with Workling (see http://github.com/purzelrakete/workling/tree/ma...)

    Does the data need to be accessed "row-wise" or do you tend to want to grab all 3,000 rows each time? If the answer is the latter, then the data should not be kept in rows. Let us say that it is a Hash, and you want to grab it once, update the 3,000 items, and save it back at once. What you would want to look at is the ActiveRecord "serialize" feature which allows for saving a big object as one column value. If you want to know more about this, let me know.

    If it is the former -- the data has to be accessed row-wise, and you also need to update 3,000 rows at a time -- we should talk.
  • I serialized the rows, and it seems to be much quicker now
  • Very good. Did you use a "text" column for the data?
  • yes
  • Must you save every single word? Or can you be more selective?

    How much RAM is on your computer?
  • In order to get a decently populated database I decided to try Hpricot's rival, Nokogiri for html scraping. I'm puzzled as to how to point the parser to a directory of docs as opposed to individual documents. It can't be too different from the way Hpricot does it. Has anyone had experience with this? Thanks.
  • Here's my code from file asanas_helper.rb:



    require 'rubygems'
    require 'open-uri'
    require 'nokogiri'

    module AsanasHelper
    def self.feed

    doc = Nokogiri::HTML(open('http://www.yogabasics.com/asana/postures/*.html')) #this doesn't work.

    poses = doc.search('/html/body/div/div/div/div[5]/div[div/div/span/@class="pathway"]')

    postures = []

    poses.each do |pose|

    english = pose.search('span[@class="pathway"].first').text
    . . . .
    postures << {:message => "searching yoga plexus", :english => english, :sanskrit => sanskrit, :basic_instruction => basic_instruction} #:difficulty => difficulty, , :benefits => benefits, :contraindications => contraindications
    end

    return postures

    end
    end
  • If you can get that to work with hpricot, do it with hpricot -- I wasn't aware that you could glob (*.html) with hpricot in the first place.
  • Nokogiri seemed simpler to me and the reviews seemed quite positive. I never tried Hpricot. The glob I wrote was just to show what I was trying to achieve, although I understood that wasn't the way to do it. I guess what I'm asking is, how would you suggest handling this in ruby? Would I need to use "mechanize"?
    thanks
  • You say something like:

    filenames = Dir.glob("*.html")
    filenames.each do |filename|
    doc = Nokogiri::HTML(open(filename))
    end

    see http://www.ruby-doc.org/core/classes/Dir.html#M...
  • If you want to scrape only, use hpricot or nokogiri. If you want to "click buttons" on a live web site, and follow links, etc., then you would additional want to use Mechanize.

    In your case: Use hpricot or nokogiri.
  • How do you do it in hpricot?

    My experience with Nokogiri is that it's not quite there yet.
  • Where is everybody?

    Can anyone suggest a good summary of the differences between all the different ajax remote tags and when to use which?

    Thanks.
  • Quick question about links/routes/atom feeds:

    I'm exposing an atom feed for a user at the url: http://localhost:3000/posts/feed/username.atom

    In my posts controller:
    def feed
    @user = User.find_by_login(params[:id])
    @posts = @user.posts.find(:all, :order => :created_at).reverse
    respond_to do |format|
    format.html
    format.atom
    end
    end

    Now in the html I want to put in an link tag using <%= auto_discovery_link_tag :atom, {:controller=>:posts, :action=>:feed, :id=>@user.login }, {} %>

    But that gives me
    http://localhost:3000/posts/feed/username
    instead of
    http://localhost:3000/posts/feed/username.atom

    Is there any way I can get the suffix in there?
  • auto_discovery_link_tag :atom, { :controller => :posts, :action => :feed, :id => @user.login, :format => :atom } %>
  • Fantastic, thanks!
  • Would it be possible to get some more information about what the write up for the final project should contain, or maybe an example of what the write up should look like? I've got my project just about done, but I'm lost on the write up.

    Thanks
  • Pat,

    I just sent an e-mail out on that topic. I covered some of the expectations here: http://e168f08.plugh.org/assignments/final-proj...

    As far as length, "what it should look like," etc.: The key is to think about the audience. The audience is a developer like yourself who must understand (1) What the app is supposed to do; and (2) how it is implemented. If you are like me, this is a high standard -- I personally need very clear and complete documentation to understand someone else's work.

    John
  • last minute cleaning-
    I was making the code clean now few things don't work and I do not know why.

    My logout does not logout anymore -
    Console shows that email is genereated and sent, but i never get in my inbox.
  • Nothing is really coming to mind -- sorry!
  • Rakefile not getting packaged?
    Hi, I am trying to rake package to submit but for some reason the rakefile isn't getting packaged up. It seems to be the only file that's missing. The weird thing is, it's in the package directory but it's not in the .zip. (I'm using the zip_in_ruby script that came with metricsmine)
  • Strange.

    The e168:submit task uses the standard rake package target, so it should be grabbing the Rakefile normally.

    I just verified the e168:submit task, but I'm on a Mac.

    Just ZIP up your project with any tool -- or, if you like, use the e168:submit task and zip up the Rakefile separately.
  • Off-topic, did anyone else rsvp to that 4-week rails class at sermo that John forwarded a few days ago? I haven't heard anything back and was wondering if anyone knows if it's actually happening.
  • John, can we talk about employment with RoR?
  • Yes, by all means. Why don't you ask some questions right here.

    Here are some brief notes on getting a Rails job:

    0. The course is good for looking for a job, but it would be a component in a whole package involving who you know, what you know, and how you grow as a developer.

    1. Who: You really should start networking by going to meetings of the Boston Ruby Group (http://bostonrb.org/). For women, e-mail Amy about her new group for Women and Ruby and Boston.

    2. What: I would advise everyone to start downloading and reading code. There are countless awesome Ruby/Rails packages you can find at RubyForge and/or Github. What you want to find are full apps. Then go over the code. Also, you may well find projects that need documentation or light fixes. You would be amazed at how many sophisticated projects have open tickets that are essentially one-line fixes. To learn how to contribute patches and fixes, Google for a screencast on using Github.

    3. Growing: You need to think of your developer status as a work in progress. Make a list of things to learn. E.g., if you've never configured a Linux system, learn by doing it. If you've never used source control (e.g., subversion), set it up. If you've never used a bug tracker, set it up. All of these tools can be useful for your personal use.
  • This sounds like a plan.

    Having been laid off mid last week, a new adventure begins. I want to use this time to retool.

    The calculus I am trying to solve is how long it will take for me to become employable in RoR. It seems to me, 6 to 18 months.

Add New Comment

Returning? Login