Rails 3 and SQLite communications concerning boolians - ruby-on-rails-3

im using Rails 3.2.8 and SQLite 1.3.6
and im running into troubles changing boolian variables in the database
SQLite translates "t" and "f" as true and false
this function wont update the :approved attribute (that is default false)
def activate
#user = User.find(params[:id])
if #user.update_attribute(:approved, 't')
redirect_to "/" #this is the return i get so the update returns true
else
render "/users?approved=false"
end
end
But changing strings like #user.update_attribute(:email,'root#email.org') will update the email
how can i fix this do i need some kind of an sqlite adapter ?
i already installed activerecord-jdbcsqlite3-adapter and it messed up my app because i was too hasty and didnt notice that it was deprecated :P
i found this thread : Rails 3 SQLite3 Boolean false
but i dont understand what i need to do in order to make Rails and SQLite communicate correctly as im a newbie in rails :)
also i think its worth mentioning that im running this on windows 7 x64
UPDATE
Apparently Rails does indeed know how to communicate with Sqlite, but the i have no idea why my code dosnt work for boolians lol
in my view i have :
<% #users.each do |user| %>
<tr>
<td><%= user.id %></td>
<td><%= user.email %></td>
<td><%= user.approved? %></td>
<td>
<% if !user.approved? %>
<%= link_to 'Approve', active_user_path(user), :method => :put %>
<% end %> </td>
</tr>
<% end %>
This lists all the unapproved users and a link to activate them (set the bool to true)
and in my controller i have
def activate
#user = User.find(params[:id])
if #user.update_attribute(:approved, true)
redirect_to "/" #this is the return i get so the update returns true
else
render "/users?approved=false" #this is not rendered
end
end
and my route
match "users/:id/activate" => "users#activate", :as => "active_user"
This works for other strings like the user name, address etc but not the bool's

If the approved column on #user is a boolean, you should just pass true/false and let the database adaptor figure it out.
#user.update_attribute(:approved, true)

I solved this by using a integer migration to my users table, i have no idea as of why #user.update_attribute(:approved, true) didnt save to the database it must have had something to do with my setup
i made the migration add_column :users, :is_approved, :integer, :default => 0 and when i want to activate a user i simply flip the integer value to 1

Related

Delete action and create action for Rails version 2.3.2

Just now I am starting to study Ruby on Rails.
ruby version=1.8.7
rails version =2.3.2
I created delete and create new user action but present some errors,
the errors are:
uninitialized constant User::Id
Extracted source (around line #19):
16: <td><%= user.fname %></td>
17: <td><%= user.lname %></td>
18: <td><%= user.dob %></td>
19: <td><%= button_to "delete", :url => {:controller => :users,:action => 'destroy',:id =>user.id}, :method => :delete %></td>
20: </tr>
21: <% end %>
22: </table>
My MySQL database table is:
id fname lname dob
1 kamal vimal 2012.02.12
2 rahu sharmi 2012.05.26
3 mithun kavi 2012.03.07
Class user:
class User < ActiveRecord::Base
set_primary_key :id
has_one :id
end
My controller is:
class UsersController < ApplicationController
def index
#users=User.all
end
def destroy
# User.primary_key='id'
#users=User.find(:id)
#users.destroy
flash[:notice] = "You have successfully Delete Recode"
end
def new
#users=User.new
end
def create
#users=User.new(params[:users])
if #user.save
redirect_to_users_path
flash[:notice] = "Your record is created!"
else
render :action => "index"
end
end
end
My view is:
<% #users.each do |user| %>
<%= button_to "delete", :url => {:controller => :users,:action => 'destroy',:id =>user.id}, :method => :delete %>
<% end %>
Anyone can help me?
I see a couple of misunderstanding.
Users Controller
If you look the delete method in the controller
def destroy
#users=User.find(:id)
[...]
You are passing a symbol to the find function instead of the id from the delete request. You can get the id by using params[:id], as you have done with the create function.
def destroy
#users=User.find(params[:id])
[...]
The following are only suggestions.
I will also change the instance variable name from #users to #user here and in the new and the create method, since you are getting/build a single user.
If your routes.rb is set like
ActionController::Routing::Routes.draw do |map|
map.resources :users
end
you don't need to specify the url specifying the controller and the action in the button_to helper, but you can use the path helpers
button_to "delete", user_path(user), :method => :delete
User model
You can remove both the statements.
You should user set_primary_key only if the primary key in the table differs from the default 'id'.
The association is misused.
With the has_one method you are telling Rails the User model is related with the model 'id' through a 1:1 relation which, I suppose, is not what you want.
Final Thoughts
Read carefully the Ruby on Rails guide if you did not, it's a good starting point.
In addition, you are using a really old version of Rails and Ruby, which are not supported anymore. If there aren't any specific reason, like working on a legacy project, I suggest you to study a more recent version like Rails 4 on ruby 2.2.

Form with list below - List shows blank entry

I have a controller:
class UsersController < ApplicationController
def departments
#users_departments = current_user.departments
#new_department = current_user.department.new
end
My view looks similar like this:
<%= form_for #new_department, :url => {:action => "departments"} do |f| %>
.
<% end %>
<% #users_departments.each do |dept| %>
<td><%= dept.name %></td>
<td><%= dept.employees %></td>
<% end %>
#users_departments.each... shows me an empty department. Why? And how to solve that?
First of all - try to use REST
form_for doc
something like that:
<%= form_for #post do |f| %>
will generate link to create action in your UserController
And about #users_departments.each - maybe in your DB current_user.departments.count - return 0
I mean maybe there is no such record in your database.
Ok I found out that the magic thing is called lazy and eager loading.
What I made was changing this:
#users_departments = current_user.departments
to
#users_departments = current_user.departments.find(:all)
Rails seems to be loading the results in the view if it was called. With "find" in place the db get hit and #users_departments fetches "really" the entries. Not in view, like before.

Change a route to a controller

I have a basic app and I'm trying to destroy a record in a table called meeting_participants based on both the meeting_id and participant_id (which are columns in meeting_participants).
I have changed the destroy action in my meeting_participants_controller, to accept the meeting_id and participant_id and then delete the appropriate record.
def destroy
session[:return_to] = request.referer
#meeting_participant = MeetingParticipant.find_by_meeting_id_and_participant_id(params[:meeting_id], params[:participant_id])
#meeting_participant.destroy
redirect_to session[:return_to]
end
I have a button in a view I would like to use to call the meeting_participants#destroy controller, using the following code.
<table>
<% #participants.each do |participant| %>
<tr>
<td><%= participant.name %></dt>
<td>
<% participant.meetings.each do |meeting| %>
<%= meeting.name %>
<%= button_to( "Remove Meeting",
{:controller => "meeting_participants",
:action => "destroy",
:meeting_id => meeting.id,
:participant_id => participant.id },
:method => :delete,
:confirm => "Are you sure?") %>
<br/>
<% end %>
</td>
</tr>
<% end %>
</table>
I think that I am successfully sending the correct participant_id and meeting_id parameters to the controller but I am getting a "No route matches" error because my route for meeting_participants#destroy is expecting a single :id parameter instead. rake routes gives...
meeting_participant DELETE /meeting_participants/:id(.:format) meeting_participants#destroy
Does anyone know of a way to change my route to expect the two new parameters instead of id? Or maybe there is a better approach altogether. I find routes very confusing.
Thanks.
My routes.rb files is...
MyApp::Application.routes.draw do
resources :meeting_participants
resources :participants
resources :meetings
end
I'd probably create a route to handle that request. Maybe something like:
match '/delete_meeting_participants/meeting/:meeting_id/participant/:participant_id' => 'meeting_participants#delete_meeting_participants', :as => 'delete_meeting_participants'
Then, in your controller you would have an action called delete_meeting_participants that has the same logic currently in your destroy action. Obviously you would have to update your button_to with the name of the newly created action.

rails form update method not called

I try to update my settings through a form but the update function is not called when I submit. It redirects to edit_settings_path when I submit and as per serve log update is not called. Why?
<%= form_tag settings_path, :method => :put do %>
<p>
<%= label_tag :"settings[:default_email]", "System Administrator" %>
<%= text_field_tag :"settings[:default_email]", Settings['default_email'] %>
</p>
<span class="submit"><%= submit_tag "Save settings" %></span>
<% end %>
Controller
class SettingsController < ApplicationController
def update
params[:settings].each do |name, value|
Settings[name] = value
end
redirect_to edit_settings_path, :notice => "Settings have been saved." }
end
end
** Update **
Update is now called properly (edited controller). Server log confirms Settings Load (0.2ms) SELECT "settings".* FROM "settings" WHERE "settings"."thing_type" IS NULL AND "settings"."thing_id" IS NULL AND "settings"."var" = ':default_email' LIMIT 1
UPDATE "settings" SET "value" = '--- 1111aaa2222...', "updated_at" = '2011-12-18 21:03:21.782075' WHERE "settings"."id" = 2
However it doesn't save to the Db and have no clue why. I'm using the Rails-settings gem 'git://github.com/100hz/rails-settings.git'
Don't know where to check since it says it updated record but in fact no.
why are you using the form_tag method?
If you are just trying to make a standard update form, use:
<%= form_for(#settings) do |f| %>
FORM CODE
<%= end %>
Your controller uses the edit method to render the view and the update method for the calback (to interact with the model)
If you insist on using
<%= form_tag setting_path, :method => :put do %>
Normally you would use the singular word if you are working on a member and the plural if you are working on an collection.
fyi: I dont know what your design is like, but i would have a model settings and a model settings_item...

How do I pass checkbox collection values in a controller spec with rspec and rails 3

With rails 3 and rspec. I have a form in a view like this ..
<%= form_for current_account, { :url => admins_account_path(current_account), :method => 'put' } do %>
<div class="action">
<%= submit_tag "Save" %>
</div>
<table>
<tbody>
<% #accountships.each do |accountship| %>
<tr>
<td><%= check_box_tag "accountship_ids[]", accountship.id, accountship.admin? %></td>
<td><%= accountship.user.name %>
</tr>
<% end %>
</tbody>
</table>
<% end %>
And in the controller, I handle the PUT with this method in accounts#update_admin. This is all working as expected.
#account.assign_administrators params[:accountship_ids]
My question is how do I construct the parameters in rspec to test that controller action. What I have tried so far is not working. Here's my latest try that doesn't work.
before(:each) do
# code that generates the ids, I know this is working from other tests ..
.
.
.
#attr = {
:accountship_ids => [
#admin_accountship.id,
#not_admin_accountship.id,
#signed_in_user_accountship.id
]
}
end
it "should assign admin to users in the list" do
# what should I be passing in as #attr?
put :update_admins, :id => #account, :accountship_ids => #attr
Accountship.find(#admin_accountship.id).admin.should be_true
Accountship.find(#owner_accountship.id).admin.should be_true
Accountship.find(#not_admin_accountship.id).admin.should_not be_true
end
All the tests I've been able to write that require values from the form checkbox collection are failing, and it's apparent that the whatever_accountship.admin attribute is not being updated when the rspec test is posting the data.
Thanks in advance!
EDIT
I stumbled onto the solution. The array shouldn't have been wrapped in a hash, and the values in the array literal needed to be converted to strings first, as below.
#attr = [
#admin_accountship.id.to_s,
#not_admin_accountship.id.to_s,
#signed_in_user_accountship.id.to_s
]
Anyone understand why they need to be strings when other tests I have can accept a full-blown object (no strings required)?
Also, what do I do to my question now that I know the answer?
It looks like you're assigning the params hash to an instance variable and then making a new hash with the first hash as the value and passing the whole mess in the put statement, when all you need to do is pass the original params. Or in other words:
put :update_admins, :id => #account.id, #attr
EDIT
Sorry, long day. The params need to go into a single hash following the action, so:
put :update_admins, {:id=>#account.id}.merge(#attr)
EDIT 2
The hash syntax will work if you pass strings in the array:
#attr = {
:accountship_ids => [
#admin_accountship.id.to_s,
#not_admin_accountship.id.to_s,
#signed_in_user_accountship.id.to_s
]
}
If you want to resolve the question with your own answer, I think you can just create an answer and then accept it.