RailsCasts Pro episodes are now free!

Learn more or hide this

Recent Comments

Avatar

Ryan,

I looked at the actual cookie... call me stupid if you want but I could not make heads or tails of the encoding used to get the info in there.

having access to the actual data of the session would allow some interesting behaviors on the client site (like displaying a different set of links when a user_id is available)

Avatar


Hi Ryan,

I did your example and everything is running so satisfactory: the table this categoreis_products storing exactly what I wanted. but the question is:
How do I get that in view of products I can redeem all the categories related to it?
maybe, you could show me a piece of code with this implementation!

ATT

Marco

Avatar

hi Ryan! this was beautiful!
anwyay, i tried it on barebones projects and it worked! (only after i realized/overlooked a stupid mistake).

um, anyway, i was hoping i could incorporate it with your complex forms projects (episodes 73-75) and i tried and..... i can't get it to work. no matter how hard i squeezed my brain i can't seem to find the answer anywhere. i can't seem to make it cooperate with the "fields_for" method :(
the problem is that "text_field_with_auto_complete" doesn't seem to recognize for example, "auto_complete_field" of
<% fields_for "student[class_record_attributes][]" do |auto_complete_field| %>
when i use it like this:
<%= text_field_with_auto_complete :auto_complete_field, ...

any ideas? @_@

Avatar

@mellifluidic et al.
So with the latest edge rails, there's a new feature for mass-assigning hash attributes, which uses an ":accessible => true" parameter appended to any has_one, has_many, etc in the model file.
http://github.com/rails/rails/commit/e0750d6a5c7f621e4ca12205137c0b135cab444a
I think this is similar to the "attr_accessible" method used before in the user.rb, but this also seems to allow these sort of forms to be created:

<% form_for @user do |f| %>
  <%= f.text_field :login %>
  <% fields_for :phone_numbers do |pn_f| %>
    <%= pn_f.text_field :area_code %>
    <%= pn_f.text_field :number %>
  <% end %>
  <%= submit_tag %>
<% end %>

So you don't have to mess around with "[new_phone_attributes]" or any custom attribute setter methods. This is GREAT!
I've only just learned about this, as it's very new, but I'll try it out and post any findings.

One thing that I already see as a possible snag is the use of AJAX-updated selects (for instance) in any of these nested resource form-segments.
EX. If I have a user with N number of addresses, where each address form has a country_id SELECT with a dynamically-updated region_id SELECT, then there will probably be conflicts when one country SELECT tries to update it's (and only it's) region_id SELECT.

hm, anyways. I'll be back.

Avatar

Hi, I'm trying to get this up and running in a scenario in which a person has a state and a state has a country, but a person doesn't have a country except through the state. In this case, the collection_select for country won't work. I'm trying to use a combined call to select_tag and options_from_collection_select to give me just the tags, but I haven't been able to get it to work yet.

I've also taken pimpmaster's suggestion about formatting, and should also mention that as with Vysogot, I'm trying to do this with something structurally similar to the projects/tasks application which is explored in the three part complex forms series. I haven't gotten too deep into trying Vysogot's solution for this to see if that get's things working, but I figured I would see if anyone could could me a quick suggestion on approach - I'll post more when I figure out more.

Cheers

Avatar

@klickverbot:

Still on the "noticed unimportant details", its funny how the screencast jumps through time. It goes to show that either:
a) Ryan's clock moves faster than ours.
b) Ryan's editing work is very good (I never notice it)

If you look at the timestamp on his comments on the screencast, they are spread over more than 1 hour, and yet the screencast is a little over 13min.

Avatar

I noticed some really unimportant detail while watching this brilliant episode: How comes your example post has the post id 53582982? That must be a really vast example application ;)

Avatar

I fixed my issue - it was with my method of calling a collection_select in my form. I had :index => '' under my html options. I think I tried this at some point while I was trying to get thing to work in part II, but found another solution and failed to take out that bit (Incidentally, the solution which worked was calling the collection_select directly on the task_form, which I had trouble doing at first because I didn't realize that when you did that you had to drop what would have otherwise been the first argument, task, in this case). So anyway, I think I'm good to go.

@glennpow: I think I'm going to have to do what you are trying to accomplish as well, so I will share any good solution I may come up with - I would also be grateful if you did likewise.

Cheers

Avatar

is there a way to keep from having to step through rails own libraries ? I'm only interested in my code. Thanks.

Avatar

For those who are having stack overflow problems. Setting
config.cache_classes = false
to true fixed it for me. Unfortunately this has the side effect of making it that models do not reload every time you use them.

Avatar

So, has anyone effectively made this work with compound models?
EX. - Where a Project can have multiple Tasks, which can have multiple Milestones, which can have multiple Assignees,...

I seem to have everything working other than getting the parameter names to be correctly parented.

I've thought of several solutions such as passing into each partial a 'parent_attr' local which (if not nil) would be prepended to the field names. But I don't think this is the most elegant method.

any other suggestions would be greatly appreciated.

Avatar

@Matthew, great points.

1. Yeah, a Set could be better since the order isn't important. I was also considering storing just the last comment id.

2. I was wondering about this. Isn't a session automatically created anyway (for the flash message)? An empty array would be very small but I suppose could build up.

3. A helper module could work and may be better for this simple example. But if things get more complex I think having its own class will scale better. This way it can have instance variables outside of what is in the session, and you can have private methods, etc and not have to worry about conflicting with existing controller methods.

@Bryce, check out episode #33. It's pretty old, but most of it still applies. I hope to do a new one on gems sometime in the future.

@Jean-Marc, as you mentioned having shared state across multiple servers is one of the things it solves. Another reason is that sessions are a pain to manage. You need to set up a separate cron job or something to remove old sessions. I think storing sessions in Memcachd is probably preferred, but not everyone has that setup.

Avatar

Ryan,

I'm still trying to get my head around the advantages of storing the session in a cookie instead of on the server... I guess it allows to have multiple servers running with no state at all (since the state is completely stored on the client)... what other reason you'd see for using the cookie session store?

Avatar

I didn't know you could have non-ActiveRecord based models.

Could you please do a screencast on how to make plugin/gemplugins?

Avatar

This is a great video, and I think it's good to avoid requiring user logins whenever possible.

- Depending on the number of comments stored in the session, it might be worth replacing the Array of comment ids with a Set.

- While it looks cleaner, moving the initialization of session into 'initialize' rather than on-demand will end up giving every visitor to your site a session, most of which will be empty.

- Could you simply make a helper module that is included in the controller and exposed to the view? It has direct access to session, and could privately define UserSession to avoid the HTTP/Model layering debate.

Avatar

@Dominic: I started making my last post before you made yours, so I didn't see that as I wrote. Sounds like you are good to go though.

Avatar

@Dominic: I (after a bit of futsing with mistyped fields) have indeed gotten this to work for the simple model used in the railscast. What version of Rails are you running?

@All: While implementing this technique with my own application, I got through the first and second casts in this series without problem, but when I went through the steps in this one, I now get the following in my log:

/!\ FAILSAFE /!\ Tue Jul 22 15:49:37 -0700 2008
  Status: 500 Internal Server Error
  Conflicting types for parameter containers. Expected an instance of Hash but found an instance of Array. This can be caused by colliding Array and Hash parameters like qs[]=value&qs[key]=value.

I'm gonna keep digging and see if I can figure out why something is getting sent an array that is supposed to be a hash (my guess is that it is the params hash), but I figured I would drop a line and see if anyone could quickly spot my problem here. I'm still pretty new to Rails, so any help is appreciated.

Thanks

Avatar

Ok, so I got it working by mashing together some code from above into the code in the book, and replacing all the instances of project_path with actions and ids as appropriate in my controllers and views.

Avatar

@Isaac, functionally it sounds like that solution works, however I'd prefer to use a sweeper instead of an observer if you need access to request specific info on a callback (such as the session).

Generally I like to keep my models (and observers) very dumb about the request details. This UserSession model is pushing that limit a bit, but since I'm not passing it directly to other models I feel it's okay.

Avatar

Its funny you should post this now. I had to come in last weekend to solve this issue for my intranet site. I ended up implementing a version of the method layed out here http://www.zorched.net/2007/05/29/making-session-data-available-to-models-in-ruby-on-rails/ which uses a user info module that stores info in the mongrel thread. Can you think of any advantages / disadvantages to doing it that way? Perhaps you could compare and contrast for extra credit? :p

Avatar

@Lenary, yep that would work if you like that logic better. You would just have to check if another comment has been created after the given comment with that same article_id.

What you have to be careful of is that if the user is currently editing a comment and in the meantime another user posts one. Then they can't submit their edit. Using 15 minutes tells the editor they have that amount of time guaranteed to make the change.

Avatar

surely it would be cleverer to find out if there have been any comments on the post since, and if not then let them edit it... that would work far better than 15 mins IMHO. I don't know how easy that would be to do though

great podcasts though, i really love them

Avatar

I ran into a little gotcha, well at least it was a gotcha for a noob like myself.

Results were not as intended, checked dev server and noticed a "406 Not Acceptable" error. A little research on Google provided: "406 Not Acceptable is for when the server cannot return the response body in any of the formats specified in the request's Accept header."

I then guessed that I needed to update my controller (built from scaffolding) to accept rjs and included a: format.js { render :rjs => @products }

Reload, refresh, and viola! Hope this helps any other Ruby & Rails noobies such as myself.

 

Avatar

My bad, I never bothered to look at how the cookie store actually saved the data in the browser. Since it seems to be encrypted, my privilege escalation point was totally wrong. Thanks for clearing this up, and keep up the good work.

Avatar

My bad, I never bothered to look at how the cookie store actually saved the data in the browser. Since it seems to be encrypted, my privilege escalation point was totally wrong. Thanks for clearing this up, and keep up the good work.

Avatar

@xhan the RSS feeds are working for me. Which link specifically doesn't work?

@Tony, the cookie session store is encoded and doesn't allow users to edit it. I'm not entirely sure how it works, but I know it's secure.

One thing it doesn't do is hide the contents from the owner of the session, but as long as you don't mind them seeing what's inside the session then you don't have to worry about it. Here we don't care if they see the comment ids so a session works fine.

Avatar

Since the session store is now saved in a cookie, wouldn't this permit any user to edit any comment added to the system if they typed the id of any comment added within the last 15 minutes into their cookie?

MySQL seems to start auto incrementing ids at 1 and increments by 1. So, it'd be fairly trivial to guess the id of the latest comment by just looking at the URL of a create comment URL.

Why not just key the comment_ids off the Rails _session_id from a Rails.cache rather than risk a privilege escalation attempt? Or, recommend switching the session store to memcached or the old PStore.

Avatar

is there any problem with rss links?
I cannot display it

Avatar

@Jonathan, non Active Record models are usually good when you have business logic that doesn't really fit anywhere else. This varies from app to app.

One thing to watch out for is RESTful controllers which don't map directly to an existing model. Instead of filling the controller up with the logic, make a custom model.

Edit: I forgot to mention. The model directory is included in the load paths, so that's how it can find the UserSession class.

@Rainer, that'll work. I prefer to blur the lines a bit between Active Record models and other models. What concerns me more is the type of logic which they contain - and in that sense they are very similar.

I usually keep the lib directory for logic which is not specific to my application - it has no knowledge of existing models and is usually more generic. Usually these are good candidates to move into a plugin or gem.

Avatar

Usually, if i use a kind of non-database-stored class, i don't put it into app/model. I prefer putting it into lib, but that's just my preference.

Avatar

Excellent stuff!

Maybe you've already touched on this before (forgive me if so), but I'm curious to know what are some other scenarios where non-Active Record models are helpful?

Also, how does Rails know how to find that user_session model? Does it just load any .rb files inside the models directory?

Avatar

This is a pretty off-scope, but:
I have added a login_at-column to my User-model to keep track of the user-logins. However, I feel that there must be a better solution than updating the database on each and every action.
I guess sessions won't work as they are stored client side, but isn't it possible to cache the time of the last login?
However, I'm still trying to figure out how to write the changes from the cache back to database, as soon as it expires.

Maybe someone can give me a hint on this.

Avatar

Another good one. Thanks again.

Avatar

@Morten it's coming soon. :)

@taelor, not sure what you mean by expiring a particular comment_id. Could you give an example?

@Karmen, fixed.

Avatar

@taelor, I agree. Maybe this should be tagged under 'Models' instead of or in addition to 'Active-record'.

Avatar

Is there someway you could set the session to expire a particular comment_id in 15 mins?

Thanks for re-pointing out that you can (and should) still have classes that are not part of Active Record. Sometimes I forget that. A Shopping Cart could be another good example.

Avatar

@Jeff Dean, Thanks for the tip about the "h" method. I was getting XHTML warnings about my titles before and that cleaned them right up.

@Ryan Bates, I think I have learned more about Ruby and Ruby on Rails from you than anyone on the planet. Thanks!

Avatar

@nerb - A quick follow up. Add this to your deploy.rb:

task :after_update_code, :roles => [:web, :db, :app] do
  run "ln -nfs #{deploy_to}/#{shared_dir}/config/database.yml #{release_path}/config/database.yml"
end

Avatar

@nerb -

If you use Capistrano, it pays to exclude the log files and database.yml from git, then create the files in the shared/ folder (that is shared between different releases) and then symlink them into your project.

The benefits of excluding those files from source control are huge when you have a handful of developers, each with a different machine configuration.

Avatar

Hello,
I am new to rails. I'am using nifty-generators. When i scaffold page, i get in views
<% title "Pages" %>. I am making this at fresh rails project. When i run mongrel, I get error like this: "undefined method `title'". How to fix this?

Avatar

Excellent and helpful as always. Thanks Ryan!

Avatar

Hi all,

I've tried out some cases for the .gitignore file. How this file have to be if I would exclude all file except two?

# .gitignore
*
!days.txt
!directory

But if I add a file to directory I get a message, that I have to use git add -f to add to the staging area. Could anyone help me?

Avatar

Hey!! Frederico de Souza I Pablo from Chile look for you and find you, I believe.
Someone know his your mail to contact it, he was a great friend.
my mail is: ramzeone@hotmail.com

THANKS!!

Avatar

Lately I have been using a search controller, which I use the new action from to start of a complex search. I have been working on a search engine at work, which needed the most complex search code I have ever had to write. Finally I came up with this: http://www.styleless.nl/search.rb

It's still really slow, takes about a minute before the search is complete (any hints anyone? ;)). I'm still refining it at the moment, but I'm going to take this to a search model after watching this :)

Thanks (again) for a great screencast.

Avatar

How do you get ruby-prof installed under osx? I've tried under both Tiger and Leopard and I get
No definition for prof_get_cpu_frequency

No definition for prof_set_cpu_frequency

on both

Avatar

hey Ryan, still working on that image trouble. I'll let you know when i get it sorted out.

had a tricky scope question though.

Is it possible to order a find call my an associated model's attribute.

e.g.

@category.members.order_by_members_businesses_names do |member|

i would just do

@category.businesses.order_by_name do |business|

but i the member model has addtional info i need to access.

named_scope :order_by_members_businesses_names ...?