RailsCasts Pro episodes are now free!

Learn more or hide this

Recent Comments

Avatar

Thanks for the post. For the views we can replace the
<%if ..%>
<link_to ....
<%end%>
with link_to_if method. It is much nicer.

Cheers
Behrang

Avatar

tried http://pastie.org/184873 (unable to get it to work)

Problem:
I am trying to use autocomplate, for the nested/parent resource places, when creating an shift.

If the place exsists, it works
if the create action is called, I get the error:

error:
Mysql::Error: Column 'user_id' cannot be null: INSERT INTO `places` (`name`, `created_at`, `updated_at`, `user_id`) VALUES('Herlevvidovre', '2009-11-28 10:42:48', '2009-11-28 10:42:48', NULL)

My setup:
map.resources :users do |users|
    users.resources :pays
    users.resources :places
    users.resources :shifts do |shifts|
      shifts.resources :payroles
    end
  end

model:
def place_name
    place.name if place
  end
  

  def place_name=(name)
    self.place = Place.find_or_create_by_name(name, @user) unless name.blank?
  end

places controller:
index:
@places = @user.places.find(:all, :conditions => ['name LIKE ?', "%#{params[:search]}%"])

create:
@place = @user.places.build(params[:place])

shift form view:
<%= text_field_with_auto_complete :shift, :place_name, { :size => 15 }, { :url => formatted_user_places_path(@user, :js), :method => :get, :param_name => 'search' } %>

Avatar

Hi,

I'm using authlogic + delcarative auth.

How to I get the access the name of a logged-in user's role? I need it for routing, too.

e.g.,
if session[:role] == 'admin'
  redirect_to admin_path
else
  redriect_to employee_path
end

I've tried find_by_name, but without success.

Thanks.

Steve

Avatar

Thanx for the tutorial. One thing you should not forget is to create the migration. I only copied the code above. It raised a bunch of errors I couldn't solve until I discovered I've missed the migration.

Avatar

Great screencast! But stubbing :valid? doesn't help when the underlying database table has the :null => false constraint on any of the columns. The database will complain when the controller tries to save the record. Any suggestions?

Avatar

found the answer on the comments:

http://apidock.com/rails/ActionView/Helpers/FormHelper/form_for

Avatar

Thanks! Recently I've been reading the RSpec beta book from Pragmatic Programmers, and it was not too much clear for me. Now I think I've finally understood how this works.

Avatar

the problem that @Frank & Javier #31 mention could be perfectly fit with the <a href="http://railscasts.com/episodes/43-ajax-with-rjs">episode 43</a>, wich by the way, i am really interesting on how to solve.

@ryan (or anybody), can you please post some link/solution?...thanks.

pd: link to pastie on #32 is broken.

Avatar

@gene: The tool for irb is called 'hirb' and could be found here:
http://github.com/cldwalker/hirb/tree/master

Avatar

I am sure this question has been asked before, however I can't find an answer for it: how do you get model print as tables in the rails console?

I really love that feature!

Avatar

How do you use this with nested fields for? when I use the check_box_tag I can't find what to pass it (first parameter) to make it create the name correctly:

here is an example of the name:
family[person_attributes][0][registration_attributes][0][weeknights][1]

Avatar

If like me you want to debug the daemon and want full backtrace logs instead of the truncated logs then do:

log_output: true

in your daemons.yml file (from the daemon generator)

then you should have in your log directory a file named daemon-name.rb.output

which has full output including backtrace and line numbers for errors etc.

Avatar

@Derano

Thanks for the Tip on nested ActiveResource!

Avatar

Use rake
db:seed SEED='file_matching_ pattern'
for specific file to populate the database.
Enjoy and do not again repeatedly update all the seed_fu dependent tables again and again

Avatar

hi everyone,

I have a question about cron in ruby. At the same time rails can running multi threads( requests). Example:

30 * * * * rake RAILS_ENV=production schedule:reload_30minutes

5 * * * * rake RAILS_ENV=production schedule:reload_5minutes

How do it?
(thanks)

Avatar

very excited about CanCan, will be giving it a trial run in one of my apps very soon.

Avatar

I love the content on the site, it's been a great help in learning rails.

As for the spam problem, you might want to just integrate askimet via
http://github.com/jfrench/rakismet and let it do the work of distinguishing between the ham and spam.

Avatar

Note: Using bitshift is better and more readable. Did you know you there was a bit reference built-in?

fixnum[bit] => 0 or 1, so:

ROLES.reject { |r| (roles_mask || 0)[ROLES.index(r)].zero? }

Avatar

@JRB: Can you explain how to resolve the error with 'unknown' method site_url in articles/show page and where to put polymorphic_path([comment.commentable, comment]) as you adviced in your post? Thank you.

Avatar

Hi there.

I'm using nifty-config and the whenever gem. But the values set in app_config.yml are not recognized when running the "whenever --update-crontab" command.

How do I fix this? Any suggestions?

Avatar

I still like my stab at authorization: http://github.com/Adman65/AccessControl

Avatar

You are my rails hero. I'm somehow a beginner and your topics can be challenge, but they are far the best and most entertaining way for me to learn RoR.

Thanks!!

Avatar

For this kind of situation I've just used individual Boolean attributes on the models -- sure, you end up with a bunch of attributes, but they're all independent so you can add or remove them as desired. Though you do then need to worry about keeping "attr_accessible" up to date...

Avatar

Awesome cast as usual Ryan.

My tuppence - I think that roles do belong in a separate table and with associations to actions,
the actions(create, edit, post review, delete etc...) are application not the roles these are arbitrary. Thoughts?

Anyway I do think the mask idea is cool concept and would be fine for such a simple Auth app.

Avatar

Thanks for the great episode, Ryan. I would like to make a note here for anyone else stuck on paths for the comment resource. Typically, you would use comment_path(comment) in your partial with map.resources :comments in your routes.rb. Or if it was a nested resource, article_comment_path(article, comment) would work; but we can't do that here, because we don't know if we should use article_comment_path, photo_comment_path, or event_comment_path!

The solution is to use polymorphic_path([comment.commentable, comment]), as mentioned in Module
ActionController::PolymorphicRoutes. Hope that helps someone else out.

Avatar

Something like reset\change password, or a basic role system :)

Avatar

Well that makes it twice today I wrote without looking. I must tired and I sincerely apologize for the lousy posts.

My code works fine once I opened my eyes, saw the 'protected' error and realized this is the one model where I hadn't update the attr_accessible.

To end on a positive note, it is good to know that, by combining your techniques, I can create nice DRY complex forms using appropriate models and associations.

Thanks Ryan!

Avatar

I ran into a problem trying to combine this technique (using Many-to-Many) with formtastic and multi-model forms (using the complex forms example for 2.3 that you have out on github).

My code for the partial that is not saving correctly looks like this:

http://pastie.org/713110

When I was using a string field to hold this information, the form worked fine. Now it displays correctly (the correct checkboxes are checked) but, when I edit and try to save, the changes to the days are not recorded.

Here Showtime::DAYS is collection of weekdays (Mon - Fri) and I using a days_mask in my database.

Since I followed your tutorials for complex forms, formtastic and now this to the letter (changing only the field names to suit), I thought you might be uniquely able to discern why the new days don't save in the complex form.

As you can tell, I'm a BIG fan!

Avatar

Ryan,

Another solution to the issue raised by @QuBiT might be to delete a role by replacing the name with a placeholder string, like -deleted-

Of course the code would be a bit more complicated since you wouldnt want the -deleted- roles to render checkboxes, but I'd probably move that logic from the view to a helper method anyway.

Avatar

Anyone experiencing issues with model.update_attributes command inside delayed jobs? I can't seem to get them working.

Avatar

This works Great...

Until I try to edit a record with a Category assigned. In my case the system produces a "SystemStackError in Inventories#edit" stack level too deep

I'm using this code: <%= text_field_with_auto_complete :inventory, :tag_name, { :size => 15 }, { :url => formatted_tags_path(:js), :method => :get, :param_name => 'search' } %>

It works with unpopulated data in create and edit, it does not edit existing data and always produces the Stack level too deep message

Anyone else having this problem?

Avatar

I just love bitmasks

Avatar

Here's a neat trick that works with your code to add magic methods like "user.admin?":

http://gist.github.com/241546

Avatar

Great job as usual, thanks Ryan !

It's good to see good old bitmasks.

I'll add a little improvement: ActiveSupport's `Array#sum` takes a block and the bitshift operator is faster than the exponentiation one, so a nicer way to handle this could be http://gist.github.com/241532

Avatar

I just installed Cucumber and Ruby on Rails on a Fedora 12 virtual machine. I am having the following issue complaining about jopenssl. Any ideas what could be wrong? Thanks

[root@bldr-vcm25 blog]# rake gems:install RAILS_ENV=test --trace
(in /home/aavella/Documents/blog)
** Invoke gems:install (first_time)
** Invoke gems:base (first_time)
** Execute gems:base
** Invoke environment (first_time)
** Execute environment
rake aborted!
no such file to load -- jopenssl
/usr/local/lib/ruby/gems/1.8/gems/rails-2.3.4/lib/initializer.rb:271:in `require_frameworks'
/usr/local/lib/ruby/gems/1.8/gems/rails-2.3.4/lib/initializer.rb:134:in `process'
/usr/local/lib/ruby/gems/1.8/gems/rails-2.3.4/lib/initializer.rb:113:in `send'
/usr/local/lib/ruby/gems/1.8/gems/rails-2.3.4/lib/initializer.rb:113:in `run'
/home/aavella/Documents/blog/config/environment.rb:9
/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.4/lib/active_support/dependencies.rb:156:in `require'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.4/lib/active_support/dependencies.rb:521:in `new_constants_in'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.4/lib/active_support/dependencies.rb:156:in `require'
/usr/local/lib/ruby/gems/1.8/gems/rails-2.3.4/lib/tasks/misc.rake:4
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:636:in `call'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:636:in `execute'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:631:in `each'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:631:in `execute'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:597:in `invoke_with_call_chain'
/usr/local/lib/ruby/1.8/monitor.rb:242:in `synchronize'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:590:in `invoke_with_call_chain'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:583:in `invoke'
/usr/local/lib/ruby/gems/1.8/gems/rails-2.3.4/lib/tasks/gems.rake:17
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:636:in `call'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:636:in `execute'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:631:in `each'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:631:in `execute'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:597:in `invoke_with_call_chain'
/usr/local/lib/ruby/1.8/monitor.rb:242:in `synchronize'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:590:in `invoke_with_call_chain'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:607:in `invoke_prerequisites'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:604:in `each'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:604:in `invoke_prerequisites'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:596:in `invoke_with_call_chain'
/usr/local/lib/ruby/1.8/monitor.rb:242:in `synchronize'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:590:in `invoke_with_call_chain'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:583:in `invoke'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2051:in `invoke_task'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2029:in `top_level'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2029:in `each'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2029:in `top_level'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2068:in `standard_exception_handling'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2023:in `top_level'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2001:in `run'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2068:in `standard_exception_handling'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:1998:in `run'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/bin/rake:31
/usr/local/bin/rake:19:in `load'
/usr/local/bin/rake:19
[root@bldr-vcm25 blog]#

Avatar

@QuBiT, you're right, removing roles can be difficult. If you need that functionality it's possible to change the roles array into a 2 dimensional array containing a static id integer. This way one wouldn't need to rely on the index position of each role.

As for your other solution of using active/inactive roles. This sounds like a role based solution which is different than the one I'm presenter here. If it is the same I'd love to see example of the code involved since I'm not certain how it would work without the tight coupling between code and database.

@David, the database matching of a comma-separated list doesn't feel as precise to me, but I can see the implementation being simpler. Thanks for the idea!

@Simon, there isn't too much code involved here: about 7 lines which replaces two models, their associations, and two database tables. Not to mention removing the coupling between the database and the code.

It really doesn't feel right to have database records so tightly coupled with code. One would need to ensure that database table is always the same in every environment (development, test and production).

I agree a bitmask can be complex, but here you shouldn't have to mess with it, and you can abstract it away more if you find the need. The underlying logic behind the alternative many-to-many assignment (role_ids= method) is actually much more complex than what we're doing here.

However, if you have an alternative solution I'd love to hear it.

@Michael, Often authorization rules are complex and difficult to map entirely in a database. However, if the authorization rules are simple enough to define in the database then keeping the roles there would make sense.

The technique I'm showing here definitely doesn't apply to every role based authorization solution. Instead it's a generic way to deal with tight coupling between the database and code.

Avatar

I agree that you had tight coupling between authorization_rules.rb and the list of roles in the DB, but I was hoping you would go the other way and show us a way to define the allowed actions of each role in the DB, too. Thanks

Avatar

Wonderful! I was actually wondering if this was posible. Thanks a lot.

Avatar

Have a look at the FlagShihTzu plugin that handles all these things for you:

http://github.com/xing/flag_shih_tzu

Avatar

thanks for another great screencast Ryan. Railscasts has become a wonderful reference guide for me. When I'm tackling a given a problem I often remember an episode that covered that topic and I go back and watch the relevant episode again.

Avatar

I'd be afraid of this making my relationships too complex. I'll give it a try!

Avatar

Way too much code for this simple little thing. I don't really see the improvement in contrast to the added amount of code, which makes it more confusing if you don't know it.
This must be documented more carefully and so on and so on.

Of course it's a common approach to use bitmasks, but sometimes it's way too much.
Have fun maintaining (and especially changing) this...

KISS ;)
Simon

Avatar

@Ryan, thanks a lot for introducing me the bitmask concept. Definitely I will use it in my project.

Avatar

Ryan, you're my role model ;-}

Avatar

Make that "role like '%admin%'".

Avatar

I would probably go for a comma separated approach myself. And use a "role like 'admin'" query if I need to fetch all admin users etc.

In my mind that would make everything more obvious both in looking at the code and the database.

Still interesting to learn about the bitmask approach though!

Avatar

undefined method `site_url' for #<Comment:0x4a8993c>, - that is No helper in the source code found!

Avatar

the error is in 'articles/show' page, line 17:
<%= link_to_unless comment.content.blank?, h(@article.author_name), h(comment.content) %>

Avatar

@Val, comment #56. Even after trying the modified code, if you come to http://localhost:3000/articles/1, you'll get an error: ActiveRecord::RecordNotFound in ArticlesController#show

Couldn't find Article with ID=comment1 for article 1.

Thanks to Ryan, of course it's a good tuto, but I am asking myself: how can one post a tuto without event checking if it works, - so let the 'pupils' find their way themselves? There is too much to check and find why it doesn't work!

Avatar

nice screen cast and nice to see no spams (YET!!!)