Installing Mysql with MacPorts for Rails on Leopard
3 CommentsI just spent a hour going through this so you won’t have to. I thought I installed mysql using mac ports but I kept getting this error.
Errno::ENOENT (No such file or directory - /tmp/mysql.sock):
Below are the three steps you need to get Mysql running on Leopard for MacPorts.
sudo port install mysql5 +server
sudo launchctl load -w /Library/LaunchDaemons/org.macports.mysql5.plist
sudo ln -s /opt/local/var/run/mysql5/mysqld.sock /tmp/mysql.sock
Posted in Rails
3 Comments
Authentication and Authorization in Rails
4 CommentsSome say Rails is “missing” a lot of things you might expect to find in full-featured web development framework, but it doesn’t matter - what’s it’s NOT missing is a plugin system which allows you to add any functionality you need by pulling a few bits of code from other authors into your site. What I’ll be using in this example are the restful-authentication plugin for authentication and the role_requirement plugin for authorization. Both of these are hosted on github, which hosts loads of Rails plugins along with other open projects. As the name implies, they use git for their repositories, so you should install git to grab these plugins.
Setting up authentication
First, you’ll need to set up authentication. In the vendor/plugins folder of your project, run:
git clone git://github.com/technoweenie/restful-authentication.git restful_authentication
This will grab a copy of the restful_authentication plugin; you don’t need to mess with any of the code in the plugin itself. go back to your project’s root and run:
script/generate authenticated user sessions
rake db:migrate
This will set up the user model for you and insert the users table in your database. You can add arguments to the generate script such as –include-activation –aasm to enable activation emails but we’re not going to cover all of that right now.
Now, you’ll have two new controllers in your application, sessions_controller.rb and users_controller.rb. Go to each of these files and remove or comment out the line that says ‘include AuthenticatedSystem’, and copy this line to the top of the application controller instead, right at the beginning of the class definition:
class ApplicationController < ActionController::Base
include AuthenticatedSystem
and so on. The generate script should have also added these lines to routes.rb:
map.logout '/logout', :controller => 'sessions', :action => 'destroy'
map.login '/login', :controller => 'sessions', :action => 'new'
map.register '/register', :controller => 'users', :action => 'create'
map.signup '/signup', :controller => 'users', :action => 'new'
map.resources :users
map.resource :session
These give you some prettier URLs rather than, for example, /users/new to sign up and /sessions/new to login. Generally you want the first thing a user sees to be the login page, so if you want to you can make that the default by adding
map.root :controller => "sessions", :action => "new"
to your routes. You’ll also need to remove or rename index.html in the public folder.
At this point you have a basic authentication system, which is great considering how easy it is to set up, but alone it’s pretty useless. You’ll notice, no matter if you’re logged in or not, you still have full access to your app. So why did we even bother? Because now, you can add authorization to lock down actions based on roles you set up.
Setting up authorization
There are a few different ways to do this; if you want a very, very granular authorization system you can install padlock authorization which allows you to set roles per each object in your application. We decided this was probably overkill for our latest project, but I may touch on it in a later blog if we decide to use it after all. We’ll be using the aforementioned role_requirement plugin.
Back to github with us! Head back to your /vendor/plugins folder and run:
git clone git://github.com/timcharper/role_requirement.git role_requirement
Go back up to your application’s root, and run:
script/generate roles Role User
rake db:migrate
Now, you’ll have to make some manual database changes. You need to add one or more roles to the roles table, and if you have any users, assign them initial roles, if you want them to have roles, in the roles_users table. You can, of course, just add a new controller and view to make all this changeable from your application, but you’ll probably still be setting up one admin user by hand to start things off when you go live.
Now you can go about editing your controllers to make each one accept and reject your roles. For example, say I have a simple model with with a TV show, which can have one starting date. To allow only administrators to make changes, you can set up your Shows controllers like so:
class ShowsController < ApplicationController
require_role "ADMIN", :for_all_except => [:index, :show]
def index
@shows = Show.find(:all)
(The rest is standard Rails boilerplate)
A later post will probably deal with setting/changing roles within your application.
Posted in Rails
4 Comments
Rails Observer Field
1 CommentThe Rails observer field is an easy way to add an ajax select menu to your site. Below is an example to get you going.
Problem
Let’s say you have a list of users on your site and want to filter them by a group. In the example we will be using gym members.
View
<%= select "gym", :gym_id, Gym.find(:all).collect { |p| [p.name, p.id]}, {:selected => params[:gym]} %>
<%= observe_field "gym_gym_id", :url => { :action => :members_by_gym ,
:controller => :members},
:update => "member_list",
:with => "'gym='+ escape($('gym_gym_id').value)" %>
<div id="member_list">
<% for member in @members %>
<%= link_to member.name, member %><br/>
<% end %>
</div>
The first thing we do is build the select form by using the Rails Select Helper. The id of the select tag is generated by rails, “gym_gym_id”. We need to pass the id name as the first parameter to the observe field. The url parameter is pretty straightforward. The update parameter of the observer field designates which element will be updated. The “:with” parameter adds a parameter to the form named “gym”.
Post
Parameters: {"contoller"=>"members", "action"=>"members_by_gym", "gym"=>"1", "controller"=>"members"}
The “gym” parameter posted here is from the observer_field tag.
Controller
def members_by_gym
@members = Member.find_all_by_gym_id(params[:gym])
render :layout => false
end
It’s important that you add the render :layout => false or bad things will happen. We still have one more thing to do. We have our controller being hit via ajax when the select menu changes but we need to make the html that will be updated on the page. In the view/members folder we need to make a new page called members_by_gym.html.erb
members_by_gym.html.erb
<% for member in @members %>
<%= link_to member.name, member %><br/>
<% end %>
This code will be interpreted and update the “member_list” element on the page. That’s it. Rails Ajax magic.
Posted in Rails, Ruby, Technology
1 Comment
Google Charts in Rails, gchartrb
3 CommentsThis week I was playing around with Google Charts, a wonderful API for creating charts via a URL. While I developed a helper class to create charts more easily in Rails, I did a little research and realized the RubyGem gchartrb has a great API for creating these charts. Here’s a quick tutorial on using gchartrb from the ground up.
Installing gchartrb
To install gchartrb, simply use the command gem install gchartrb from your command prompt. Check out these instructions for additional help and to access the gchartrb packages (Downloadable here).
Quick Examples
Now that we have our gem installed, we can create graphs right away. First, remember to require the gem at the top of your code. Notice how the gchartrb gem is actually called “google_chart”:
1 require 'rubygems'
2 require 'google_chart'
There are a couple ways that you can create a chart. You can instantiate the graph and then add attributes to it:
1 lc = GoogleChart::LineChart.new("400x200", "My Results", false)
Alternatively, you can create the graph and add the attributes within a block:
1 GoogleChart::LineChart.new("400x200", "My Results", false) do |lc|
2 # Put lc data here
3 # ...
4 puts lc.to_url
5 end
I personally prefer the latter method, as the creation of the graph and its attributes are kept together in a modular fashion.
Here are some examples of line, bar, and pie charts:
Line Chart
1 lc = GoogleChart::LineChart.new("400x200", "My Results", false)
2 lc.data "Line green", [3,5,1,9,0,2], '00ff00'
3 lc.data "Line red", [2,4,0,6,9,3], 'ff0000'
4 lc.axis :y, :range => [0,10], :font_size => 10, :alignment => :center
5 lc.show_legend = false
6 lc.shape_marker :circle, :color => '0000ff', :data_set_index => 0, :data_point_index => -1, :pixel_size => 10
7 puts lc.to_url
Notice that each lc.data call will create a new data line for you. The second parameter accepts a integer or float array, which can be anything you like. Lets say you have a WeighIn model that has weight as an attribute and belongs to some Person. If a person weighs himself/herself once a month for a year, then we can collect that data and show your trend via a line graph. Collecting that data and using it would look like this:
# In th![[del.icio.us]](http://badpopcorn.com/blog/wp-content/plugins/bookmarkify/delicious.png)
![[Digg]](http://badpopcorn.com/blog/wp-content/plugins/bookmarkify/digg.png)
![[Google]](http://badpopcorn.com/blog/wp-content/plugins/bookmarkify/google.png)
![[StumbleUpon]](http://badpopcorn.com/blog/wp-content/plugins/bookmarkify/stumbleupon.png)
![[Windows Live]](http://badpopcorn.com/blog/wp-content/plugins/bookmarkify/windowslive.png)
![[Yahoo!]](http://badpopcorn.com/blog/wp-content/plugins/bookmarkify/yahoo.png)
![[Email]](http://badpopcorn.com/blog/wp-content/plugins/bookmarkify/email.png)