Rails 3.1
Spork 0.9 rc9
ZenTest (installs autotest binary)
Fedora Linux
After launching spork, and then autotest, any failed tests will continuously get retested by autotest. This is because autotest is looking for changes in file dates and will rerun all tests if it finds a change.
Solution:
.autotest setup can be found in
http://ruby.railstutorial.org/chapters/static-pages
and
http://automate-everything.com/2009/08/gnome-and-autospec-notifications/
Edit ~/.autotest
Autotest.add_hook :initialize do |autotest|
autotest.add_exception %r{^\.git} # ignore Version Control System
autotest.add_exception %r{^./tmp} # ignore temp files
autotest.add_exception %r{^./log} # ignore log
# from rails tutorial 201109
autotest.add_mapping(/^spec\/requests\/.*_spec\.rb$/) do
autotest.files_matching(/^spec\/requests\/.*_spec\.rb$/)
end
end
I had to add the log exception to stop the failure cycle.
Sunday, September 4, 2011
rails, devise and how to edit user account profile without providing a password
There are several options on the wiki to update an account information without providing a password
https://github.com/plataformatec/devise/wiki/How-To%3a-Allow-users-to-edit-their-account-without-providing-a-password
This is due to the fact that devise is asking for the current password for all profile changes. The wiki makes changes to remove password fields or the current password from the form.
The workflow I was looking for was to allow the user to change details such as first and last name without a password. Only when the current password is change is a password required.
Solution:
rails 3.1
devise 1.4.4
From the Gem
copy the method update_with_password and add it to your user.rb model (or whatever model you're using to store account information)
def update_with_password(params={})
current_password = params.delete(:current_password)
if params[:password].blank?
params.delete(:password)
params.delete(:password_confirmation) if params[:password_confirmation].blank?
end
result = if valid_password?(current_password)
update_attributes(params)
else
self.attributes = params
self.valid?
self.errors.add(:current_password, current_password.blank? ? :blank : :invalid)
false
end
clean_up_passwords
result
end
Next change the line
Don't check for current password if password is blank, go ahead and update
https://github.com/plataformatec/devise/wiki/How-To%3a-Allow-users-to-edit-their-account-without-providing-a-password
This is due to the fact that devise is asking for the current password for all profile changes. The wiki makes changes to remove password fields or the current password from the form.
The workflow I was looking for was to allow the user to change details such as first and last name without a password. Only when the current password is change is a password required.
Solution:
rails 3.1
devise 1.4.4
From the Gem
/gems/devise-1.4.4/lib/devise/models/database_authenticatable.rb
copy the method update_with_password and add it to your user.rb model (or whatever model you're using to store account information)
current_password = params.delete(:current_password)
if params[:password].blank?
params.delete(:password)
params.delete(:password_confirmation) if params[:password_confirmation].blank?
end
result = if valid_password?(current_password)
update_attributes(params)
else
self.attributes = params
self.valid?
self.errors.add(:current_password, current_password.blank? ? :blank : :invalid)
false
end
clean_up_passwords
result
end
Next change the line
result = if valid_password?(current_password)
toresult = if params[:password].blank? && if params[:password].blank? || valid_password?(current_password)
Don't check for current password if password is blank, go ahead and update
Sunday, August 28, 2011
Editing Aptana Key Shortcuts and rebinding commands such as open resource
Being used to eclipse pdt, the open resource command is an indispensable feature. You can open files by typing a few letters and matching filenames start appearing.
Conviently it's mapped to Control+Shift+R
Unfortunately, in Aptana, Eclipse and the Rails workspace, two other commands are bound to this same shortcut. Eclipse, being smart, will create a pop up menu with each of these commands and you can select the one you want with the mouse (typing 0,1,2 will do the same).
Anyone trying to keybind, or replace the shortcut will find that none of the Eclipse GUI menus will allow you to change it.
Solution:
Edit: One extra step, you need to download the bundle with eclipse in order to view in the Documents dir.
Click on Commands -> Select Rails or Ruby from the menu -> Edit this bundle.
Take note of the other menu items.
Mine were
Run Rake Task 1
Run Focused Unit Test 2
Open Resource 3
Aptana saves all the bundle scripts in this directory
You will find all the aptana scripts *.rb
Edit
and change '+R' in
to '+Y' or another key
Conviently it's mapped to Control+Shift+R
Unfortunately, in Aptana, Eclipse and the Rails workspace, two other commands are bound to this same shortcut. Eclipse, being smart, will create a pop up menu with each of these commands and you can select the one you want with the mouse (typing 0,1,2 will do the same).
Anyone trying to keybind, or replace the shortcut will find that none of the Eclipse GUI menus will allow you to change it.
Solution:
Edit: One extra step, you need to download the bundle with eclipse in order to view in the Documents dir.
Click on Commands -> Select Rails or Ruby from the menu -> Edit this bundle.
Take note of the other menu items.
Mine were
Run Rake Task 1
Run Focused Unit Test 2
Open Resource 3
Aptana saves all the bundle scripts in this directory
~/Documents/Aptana Rubles/ruby.ruble/commands/
You will find all the aptana scripts *.rb
Edit
run_rake_task.rb
run_focused_unit_test.rb
and change '+R' in
cmd.key_binding = 'CONTROL+M2+R'
orcmd.key_binding = 'M1+M2+R'
to '+Y' or another key
Tuesday, July 19, 2011
Renaming Capabilities in Moodle 1.9.x
On the off chance you need to rename moodle capabilities
eg.
Here is what you have to do:
1) edit upgrade.php and add two create sql statement
eg.
2) execute_sql($sql) both of them
3) The last part is that you MUST also change the mycustomblock/db/access.php to include the new capability type. This is because Moodle will compare capabilities in access.php to the ones stored in the database.
a) Moodle will search for new capabilities.
b) Moodle will delete them from the mdl_capabilities table, then add them as a new row.
c) Moodle will then delete the capability from mdl_role_capabilities. (I believe this is to preserve the referential integrity of foreign keys between mdl_role_capabilities.capability and mdl_capabilities.name)
In access.php
Add :
Look at upgrade_blocks_plugins() in blocklib.php for more info.
eg.
block/mycustomblock:viewpages
to block/mycustomblock:viewadminpages
Here is what you have to do:
1) edit upgrade.php and add two create sql statement
eg.
$sql = "UPDATE {$CFG->prefix}capabilities
SET name = 'block/mycustomblock:viewadminpages'
WHERE name = 'block/mycustomblock:viewpages'";
$sql =
"UPDATE {$CFG->prefix}role_capabilities
SET capability = 'block/mycustomblock:viewadminpages'
WHERE capability = 'block/mycustomblock:viewpages'";2) execute_sql($sql) both of them
3) The last part is that you MUST also change the mycustomblock/db/access.php to include the new capability type. This is because Moodle will compare capabilities in access.php to the ones stored in the database.
a) Moodle will search for new capabilities.
b) Moodle will delete them from the mdl_capabilities table, then add them as a new row.
c) Moodle will then delete the capability from mdl_role_capabilities. (I believe this is to preserve the referential integrity of foreign keys between mdl_role_capabilities.capability and mdl_capabilities.name)
In access.php
Add :
'block/mycustomblock:viewadminpages' => array(
'riskbitmask' => RISK_PERSONAL,
'captype' => 'read',
'contextlevel' => CONTEXT_MODULE,
'legacy' => array(
)
),
Look at upgrade_blocks_plugins() in blocklib.php for more info.
Tuesday, July 12, 2011
Make Rails Devise Routes Look Better
AKA remap the routes in Rails Devise Authentication
Anyone who explores Devise in their rails app will find that all the generated routes fall under a single path. Since most people choose the User model for saving user information, devise will put all these methods under /users/
Looking at this, I wanted to customize some of the routes so they are located elsewhere in my application. eg. Move the /users/sign_in to /login and /users/sign_up to /signup
Devise and rails routes offers a few methods of doing this which are mentioned on the Devise wiki pages, but the problem I ran into was how the registration controller was mapping over top of the users controller routes.
I would like new_user_registration to point to /signup, and user_registration to /signup too. This is cause when the form is submitted, and an error occurs we want the use to remain on the /signup URL. After some help from this post on google groups:
http://groups.google.com/group/plataformatec-devise/browse_thread/thread/cfa98fd217d558e6
I ended up with these devise routes: /login, /logout, and /signup and it puts some of the registration routes under /register, thereby leaving the user actions for my users controller and not for devise. Pretty now.
Edit: A quirk with devise is that the update_user_registration uses the same action="{URL}" as user_registration no matter what is defined in the routes. This causes the action for update_user_registration to send the put to /signup when we want it to go to /user/edit. The solution is to edit the registration/edit.html.erb and change
:url => :update_user_registration
.
Anyone who explores Devise in their rails app will find that all the generated routes fall under a single path. Since most people choose the User model for saving user information, devise will put all these methods under /users/
rake routes
new_user_session GET /users/sign_in(.:format) {:action=>"new", :controller=>"devise/sessions"}
user_session POST /users/sign_in(.:format) {:action=>"create", :controller=>"devise/sessions"}
destroy_user_session DELETE /users/sign_out(.:format) {:action=>"destroy", :controller=>"devise/sessions"}
user_password POST /users/password(.:format) {:action=>"create", :controller=>"devise/passwords"}
new_user_password GET /users/password/new(.:format) {:action=>"new", :controller=>"devise/passwords"}
edit_user_password GET /users/password/edit(.:format) {:action=>"edit", :controller=>"devise/passwords"}
PUT /users/password(.:format) {:action=>"update", :controller=>"devise/passwords"}
cancel_user_registration GET /users/cancel(.:format) {:action=>"cancel", :controller=>"devise/registrations"}
user_registration POST /users(.:format) {:action=>"create", :controller=>"devise/registrations"}
new_user_registration GET /users/sign_up(.:format) {:action=>"new", :controller=>"devise/registrations"}
edit_user_registration GET /users/edit(.:format) {:action=>"edit", :controller=>"devise/registrations"}
PUT /users(.:format) {:action=>"update", :controller=>"devise/registrations"}
DELETE /users(.:format) {:action=>"destroy", :controller=>"devise/registrations"}
user_unlock POST /users/unlock(.:format) {:action=>"create", :controller=>"devise/unlocks"}
new_user_unlock GET /users/unlock/new(.:format) {:action=>"new", :controller=>"devise/unlocks"}
GET /users/unlock(.:format) {:action=>"show", :controller=>"devise/unlocks"}
Looking at this, I wanted to customize some of the routes so they are located elsewhere in my application. eg. Move the /users/sign_in to /login and /users/sign_up to /signup
Devise and rails routes offers a few methods of doing this which are mentioned on the Devise wiki pages, but the problem I ran into was how the registration controller was mapping over top of the users controller routes.
user_registration POST /users(.:format) {:action=>"create", :controller=>"devise/registrations"}
new_user_registration GET /users/sign_up(.:format) {:action=>"new", :controller=>"devise/registrations"}
edit_user_registration GET /users/edit(.:format) {:action=>"edit", :controller=>"devise/registrations"}
PUT /users(.:format) {:action=>"update", :controller=>"devise/registrations"}
DELETE /users(.:format) {:action=>"destroy", :controller=>"devise/registrations"}
user_unlock POST /users/unlock(.:format) {:action=>"create", :controller=>"devise/unlocks"}
I would like new_user_registration to point to /signup, and user_registration to /signup too. This is cause when the form is submitted, and an error occurs we want the use to remain on the /signup URL. After some help from this post on google groups:
http://groups.google.com/group/plataformatec-devise/browse_thread/thread/cfa98fd217d558e6
I ended up with these devise routes: /login, /logout, and /signup and it puts some of the registration routes under /register, thereby leaving the user actions for my users controller and not for devise. Pretty now.
devise_for :user, :path => '', :path_names => { :sign_in => 'login', :sign_out => 'logout'}, :skip => [:registration] do
scope :controller => 'devise/registrations' do
get :cancel, :path => 'users/cancel', :as => :cancel_user_registration
post :create, :path => 'signup', :as => :user_registration
get :new, :path => 'signup' , :as => :new_user_registration
get :edit, :path => 'users/edit', :as => :edit_user_registration
put :update, :path => 'users/edit', :as => :update_user_registration
delete :destroy, :path => 'users'
end
end rake routes
cancel_user_registration GET /users/cancel(.:format) {:action=>"cancel", :controller=>"devise/registrations"}
user_registration POST /signup(.:format) {:action=>"create", :controller=>"devise/registrations"}
new_user_registration GET /signup(.:format) {:action=>"new", :controller=>"devise/registrations"}
edit_user_registration GET /users/edit(.:format) {:action=>"edit", :controller=>"devise/registrations"}
update_user_registration PUT /users/edit(.:format) {:action=>"update", :controller=>"devise/registrations"}
destroy DELETE /users(.:format) {:action=>"destroy", :controller=>"devise/registrations"}
new_user_session GET /login(.:format) {:action=>"new", :controller=>"devise/sessions"}
user_session POST /login(.:format) {:action=>"create", :controller=>"devise/sessions"}
destroy_user_session DELETE /logout(.:format) {:action=>"destroy", :controller=>"devise/sessions"}
user_password POST /password(.:format) {:action=>"create", :controller=>"devise/passwords"}
new_user_password GET /password/new(.:format) {:action=>"new", :controller=>"devise/passwords"}
edit_user_password GET /password/edit(.:format) {:action=>"edit", :controller=>"devise/passwords"}
PUT /password(.:format) {:action=>"update", :controller=>"devise/passwords"}
user_unlock POST /unlock(.:format) {:action=>"create", :controller=>"devise/unlocks"}
new_user_unlock GET /unlock/new(.:format) {:action=>"new", :controller=>"devise/unlocks"}
GET /unlock(.:format) {:action=>"show", :controller=>"devise/unlocks"} Edit: A quirk with devise is that the update_user_registration uses the same action="{URL}" as user_registration no matter what is defined in the routes. This causes the action for update_user_registration to send the put to /signup when we want it to go to /user/edit. The solution is to edit the registration/edit.html.erb and change
:url => registration_path(resource_name)
to:url => :update_user_registration
.
Monday, January 17, 2011
Drupal SOAP with NuSOAP and this error message You must specify a name when you register an operation
While looking into Drupal and Soap I ran across this choice message
Drupal 6.20
You must specify a name when you register an operation
I'm using:
Drupal 6.20
Services Module 6.x-2.4 - http://drupal.org/project/services -
Soap Server 6.x-1.2-beta1 - http://drupal.org/project/soap_server
w/ NuSOAP 0.9.5.zip - http://sourceforge.net/projects/nusoap
w/ NuSOAP 0.9.5.zip - http://sourceforge.net/projects/nusoap
The Soap Server 6.x-3x-dev has a warning: Prototype in active development - not ready for production use without careful scrutiny and testing, so I went with this older soap module dated from back in 2008. This older version uses nusoap, and is likely a lot slower than the standard php soap functions introduced in 5.x
After receiving the above message, I also ran across this patch http://drupal.org/files/issues/soap_server.patch and ran it against soap_server/soap_server.module. Seems like the soap module has already been patched to the most recent one.
Solution:
In the file drupal module - soap_server.module do a find and replace for
'
single quote.
The soap wsdl can then be retrieved.
After receiving the above message, I also ran across this patch http://drupal.org/files/issues/soap_server.patch and ran it against soap_server/soap_server.module. Seems like the soap module has already been patched to the most recent one.
Solution:
In the file drupal module - soap_server.module do a find and replace for
'#
ie single quote, pound character, and replace it with just a'
single quote.
The soap wsdl can then be retrieved.
Monday, November 8, 2010
Some simple commands to setup your first git repository coming from a subversion background.
Coming from Subversion we're used to a primary repository that we can import, do editing and commit our changes to.
Git can do this, but it may be a little slow going until you read a few pages of docs. One concept that I had to understand was that every git project directory is a repository with a history of changes. Subversion only keeps revisions on the server.
To create your a primary git repository and another directory in your main dir:
No refs in common and none specified; doing nothing.
Perhaps you should specify a branch such as 'master'.
fatal: The remote end hung up unexpectedly
error: failed to push some refs to '/srv/git/yourappname'
Reading some of the docs, one would expect you would only need to type in git push to do this. The first time you need to do:
Getting this to work with Eclipse
If you're using linux, there are a few gui's available gitg, gitk, git gui (That's the command 'git gui'). Some of us use eclipse as our primary ide, so it's convenient to have git integrated with our workflow. Here's how to set it up. Sorry I'm too lazy for screenshots. I'm using Eclipse Helios SR-1
Git can do this, but it may be a little slow going until you read a few pages of docs. One concept that I had to understand was that every git project directory is a repository with a history of changes. Subversion only keeps revisions on the server.
To create your a primary git repository and another directory in your main dir:
- First make a bare git repository
Create a directory to store this project. I used /srv/git/yourappname - cd /srv/git/yourappname and run git init --bare
This is important and it will act only as a repository. In other words without the --bare flag, a repository is created with the expectation that source files will be in this directory and will be editted. - Go to your workspace directory and import, or in git terminology - clone the project
cd ~/workspace
git clone /srv/git/yourappname myapp
- cd ~/workspace/myapp
- Edit some files
- git add .
(do this in myapp) - git commit -a -m 'my commit'
No refs in common and none specified; doing nothing.
Perhaps you should specify a branch such as 'master'.
fatal: The remote end hung up unexpectedly
error: failed to push some refs to '/srv/git/yourappname'
Reading some of the docs, one would expect you would only need to type in git push to do this. The first time you need to do:
- git push origin master
What this does is create the the master branch on the origin repository. I supposed this is like creating the trunk in svn. - Subsequent pushes only require git push to update your code on master.
- Even if you delete ~/workspace/myapp and do another clone, you will again only need to do git push
Getting this to work with Eclipse
If you're using linux, there are a few gui's available gitg, gitk, git gui (That's the command 'git gui'). Some of us use eclipse as our primary ide, so it's convenient to have git integrated with our workflow. Here's how to set it up. Sorry I'm too lazy for screenshots. I'm using Eclipse Helios SR-1
- Make sure you have the git plugin.
- If you did the above steps you can add that git project to the Git Repository Interface.
- Select 'Add an existing repository to this view'
- Select /home/you/workspace/myapp
- The repository will appear in the interface, like a repository appears eclipse subclipse.
- Click on Working Directory and select 'Import Projects'
- Go through the wizard, select your project type and tada, that's all there is. You will now have a git managed project where you can commit your changes to. Like SVN, you go to TEAM and perform the operations tasks you want.
Subscribe to:
Posts (Atom)