Newbie question: Integrating Authlogic plug-in more deeply

I have training app with “Projects” set up with nested “Tasks”. I
have integrate authlogic gem so that the app supports “Login/off” &
“Register/Modify Profile” per ryanb’s railscast. I am now trying to
use authlogic and set up UI’s so that after a user logs in, then the
user can go to a UI of “My Projects” and then do all the CRUD they
need to do on their own projects (current_user), but the user will
only have read access to projects that are not theirs (not
current_user). All users will have their Projects in the same data
model (or that’s what I’m attempting to do). I created a “myprojects”
controller, copied over the project controller code & have been trying
to work with “current_user.projects”, but I’m getting an error since
the Project is an undefined method.

How does one do this? Is there a way to pass the Project controller &
views the “current_user.projects” data to re-use the Project
controller & views? I know I’ll have to put condition logic in to
display or not display the ‘Edit’ paths, I’m just buggered on how to
pass the subset of data if this is the way to go. Do I need the
Myprojects controller or am I barking up a wrong tree? Do named
routes come into play here? Enquiring minds want to know as a famous
tabloid once advertised…

Thanks in advance!!

Following is my code:
--------------------Project controller--------------------
class ProjectsController < ApplicationController
def index
@projects = Project.all

respond_to do |format|
  format.html # index.html.erb
  format.xml  { render :xml => @projects }
end

end

def show
@project = Project.find(params[:id])

respond_to do |format|
  format.html # show.html.erb
  format.xml  { render :xml => @projects }
end

end

def new
@project = Project.new

respond_to do |format|
  format.html # new.html.erb
  format.xml  { render :xml => @project }
end

end

def edit
@project = Project.find(params[:id])
end

def create
@project = Project.new(params[:project])

respond_to do |format|
  if @project.save
    flash[:notice] = 'Project was successfully created.'
    format.html { redirect_to(@project) }
    format.xml  { render :xml => @project, :status

=> :created, :location => @project }
else
format.html { render :action => “new” }
format.xml { render :xml => @project.errors, :status
=> :unprocessable_entity }
end
end
end

def update
@project = Project.find(params[:id])

respond_to do |format|
  if @project.update_attributes(params[:project])
    flash[:notice] = 'Project was successfully updated.'
    format.html { redirect_to(@project) }
    format.xml  { head :ok }
  else
    format.html { render :action => "edit" }
    format.xml  { render :xml => @project.errors, :status

=> :unprocessable_entity }
end
end
end

def destroy
@project = Project.find(params[:id])
@project.destroy
flash[:notice] = ‘Project was successfully deleted.’
respond_to do |format|
format.html { redirect_to(projects_url) }
format.xml { head :ok }
end
end
end

--------------------Myprojects controller--------------------
class MyprojectsController < ApplicationController
def index
@myprojects = current_user.Project.all #<-------- ‘Project’
reference here is getting an undefined method error

respond_to do |format|
  format.html # index.html.erb
  format.xml  { render :xml => @myprojects }
end

end

def show
@project = current_user.Project.find(params[:id])

respond_to do |format|
  format.html # show.html.erb
  format.xml  { render :xml => @myprojects }
end

end

def new
@project = Project.new

respond_to do |format|
  format.html # new.html.erb
  format.xml  { render :xml => @project }
end

end

def edit
@project = current_user.Project.find(params[:id])
end

def create
@project = Project.new(params[:project])

respond_to do |format|
  if @project.save
    flash[:notice] = 'Project was successfully created.'
    format.html { redirect_to(@project) }
    format.xml  { render :xml => @project, :status

=> :created, :location => @project }
else
format.html { render :action => “new” }
format.xml { render :xml => @project.errors, :status
=> :unprocessable_entity }
end
end
end

def update
@project = current_user.Project.find(params[:id])

respond_to do |format|
  if @project.update_attributes(params[:project])
    flash[:notice] = 'Project was successfully updated.'
    format.html { redirect_to(@project) }
    format.xml  { head :ok }
  else
    format.html { render :action => "edit" }
    format.xml  { render :xml => @project.errors, :status

=> :unprocessable_entity }
end
end
end

def destroy
@project = current_user.Project.find(params[:id])
@project.destroy
flash[:notice] = ‘Project was successfully deleted.’
respond_to do |format|
format.html { redirect_to(myprojects_url) }
format.xml { head :ok }
end
end
end

--------------------Project model--------------------
class Project < ActiveRecord::Base
validates_presence_of :name

allow ordering of tasks by step_number

has_many :tasks, :dependent => :destroy, :order => ‘step_number ASC’
accepts_nested_attributes_for :tasks, :reject_if => lambda { |a|
a.values.all?(&:blank?) }, :allow_destroy => true

def task_attributes=(task_attributes)
task_attributes.each do |attributes|
tasks.build(attributes)
end
end

Following statements tie Projects to users

belongs_to :user

end

--------------------User model--------------------
class User < ActiveRecord::Base

following line commented out. Came from authlogic, but not sure

what it means…

attr_accessible :username, :email, :password

Added following line from railscast demo. Note:

has an optional block for passing other config options, but didn’t

go there for now…
acts_as_authentic

has_many :projects
end

--------------------Myprojects controller--------------------
class MyprojectsController < ApplicationController
def index
@myprojects = current_user.Project.all #<-------- ‘Project’
reference here is getting an undefined method error

respond_to do |format|
  format.html # index.html.erb
  format.xml  { render :xml => @myprojects }
end

end

Would that not need to read

@myprojects = current_user.projects.all

PS i’ll be impressed if i’m right being new to rails myself! :slight_smile:

Jon C. wrote:

--------------------Myprojects controller--------------------
class MyprojectsController < ApplicationController
def index
@myprojects = current_user.Project.all #<-------- ‘Project’
reference here is getting an undefined method error

respond_to do |format|
  format.html # index.html.erb
  format.xml  { render :xml => @myprojects }
end

end

Would that not need to read

@myprojects = current_user.projects.all

Or just current_user.projects , since that already returns a collection.

PS i’ll be impressed if i’m right being new to rails myself! :slight_smile:

Then prepare to be impressed. Good catch!

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Souschef wrote:

DOH!! I will have mastered rails when I KNOW where to Capitalize AND
where to put an ‘s’ in or not! Thanks!!

I worked past this error, was able to get the ‘index’ showing, but
when I go to the ‘show’ or ‘edit’ views, I get an error where the
“Project” index ID is WAY out of bounds (I don’t think my dev db has
gone beyond 20 id’s):

  ActiveRecord::RecordNotFound in MyprojectsController#show
  Couldn't find Project with ID=36732470 AND (`projects`.user_id =

[…]

Are you using fixtures? If so, then high id numbers like this are
normal.

If not, then something else is going on.

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Are you using fixtures? If so, then high id numbers like this are
normal.

If not, then something else is going on.

I haven’t tackled fixtures yet so I’m not consciously using one,
unless there is something in authlogic that’s using one that I’m not
aware of…

DOH!! I will have mastered rails when I KNOW where to Capitalize AND
where to put an ‘s’ in or not! Thanks!!

I worked past this error, was able to get the ‘index’ showing, but
when I go to the ‘show’ or ‘edit’ views, I get an error where the
“Project” index ID is WAY out of bounds (I don’t think my dev db has
gone beyond 20 id’s):

  ActiveRecord::RecordNotFound in MyprojectsController#show
  Couldn't find Project with ID=36732470 AND (`projects`.user_id =

The user_id is passing fine, but the project ID is corrupted. I’ve
tweaked my ‘Show’ definition to be current_user.project.find(params
[:id]), current_user.Project.find(params[:id]),
current_user.Projects.find(params[:id]) but these only result in “No
Method” errors. Also, the “destroy” works fine.

Any thoughts why the index is not getting passed correctly for ‘Show’
& ‘Edit’, but it’s fine for the ‘destroy’?

Myprojects controller is looking like this:

class MyprojectsController < ApplicationController

GET /myprojects

GET /myprojects.xml

def index
@myprojects = current_user.projects.all

respond_to do |format|
  format.html # index.html.erb
  format.xml  { render :xml => @myprojects }
end

end

GET /myprojects/1

GET /myprojects/1.xml

def show
@myproject = current_user.projects.find(params[:id])

respond_to do |format|
  format.html # show.html.erb
  format.xml  { render :xml => @myprojects }
end

end

GET /myprojects/new

GET /myprojects/new.xml

def new
@myproject = Project.new

respond_to do |format|
  format.html # new.html.erb
  format.xml  { render :xml => @project }
end

end

GET /myprojects/1/edit

def edit
@myproject = current_user.project.find(params[:id])
end

POST /myprojects

POST /myprojects.xml

def create
@myproject = Project.new(params[:project])

respond_to do |format|
  if @project.save
    flash[:notice] = 'Project was successfully created.'
    format.html { redirect_to(@project) }
    format.xml  { render :xml => @project, :status

=> :created, :location => @project }
else
format.html { render :action => “new” }
format.xml { render :xml => @project.errors, :status
=> :unprocessable_entity }
end
end
end

PUT /myprojects/1

PUT /myprojects/1.xml

def update
@myproject = current_user.Project.find(params[:id])

respond_to do |format|
  if @project.update_attributes(params[:project])
    flash[:notice] = 'Project was successfully updated.'
    format.html { redirect_to(@project) }
    format.xml  { head :ok }
  else
    format.html { render :action => "edit" }
    format.xml  { render :xml => @project.errors, :status

=> :unprocessable_entity }
end
end
end

DELETE /myprojects/1

DELETE /myprojects/1.xml

def destroy
@myproject = current_user.project.find(params[:id])
@myproject.destroy
flash[:notice] = ‘Project was successfully deleted.’
respond_to do |format|
format.html { redirect_to(myprojects_url) }
format.xml { head :ok }
end
end
end

====================

Souschef wrote:

Are you using fixtures? If so, then high id numbers like this are
normal.

If not, then something else is going on.

I haven’t tackled fixtures yet

Good: fixtures are crap. Use factories instead.

Bad: that suggests that you’re not developing test-first yet. Get the
habit now.

so I’m not consciously using one,
unless there is something in authlogic that’s using one that I’m not
aware of…

There shouldn’t be. Sounds like you have a problem elsewhere.

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Souschef wrote:

More info: I viewed page source for the index page & the funky
references are being passed to it. Looking at the paths it’s easy to
see why the “delete” works & the ‘show’ & ‘edit’ don’t. The href
number changes each time for the ‘Show’ (embedded in the project
title) & ‘Edit’ the index is called. Here’s a list:

Clean Room Edit Clean House Edit Mom's project Edit Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

More info: I viewed page source for the index page & the funky
references are being passed to it. Looking at the paths it’s easy to
see why the “delete” works & the ‘show’ & ‘edit’ don’t. The href
number changes each time for the ‘Show’ (embedded in the project
title) & ‘Edit’ the index is called. Here’s a list:

Clean Room Edit Clean House Edit Mom's project Edit <a href="/projects/16" onclick="if (confirm('Are you sure?')) {DELETED EXTRA CODE HERE} </tr> <p>Yes, shame on me for not starting w/ TDD… will get there once I can<br> get some rails basics under the belt…</p>

In Ruby, every object has an attached object_id reference. Those long
numbers are the ruby object_id’s. You more than likely are referencing
the object_id mistakenly.

As an example:

irb
irb(main):001:0> my_object = “”
=> “”
irb(main):002:0> my_object.object_id
=> 23323808

notice the 8 digit object_id number

… and yours:

37127550

… 8 digits.

Interesting Alpha B., it does look like that. Where might I be mis-
referncing the object other than the myproject controller?

Interesting Alpha B., it does look like that. Where might I be mis-
referncing the object other than the myproject controller?

Souschef wrote:

Interesting Alpha B., it does look like that. Where might I be mis-
referncing the object other than the myproject controller?

It can be an easy mistake to miss.

I found an old cart model a long time ago and for some strange reason, I
saved it because it had this particular issue you are having.

cart.items.each_with_index do |item, index|
item_id = Product.find_by_title(item.title)
values.merge!({
“amount_#{index+1}” => item.price,
“item_name_#{index+1}” => item.title,
“item_number_#{index+1}” => item_id,
“quantity_#{index+1}” => item.quantity
})
end

In this example, notice the item_id? It was referencing the object_id
instead of the id field. When I changed it to:

cart.items.each_with_index do |item, index|
item_id = Product.find_by_title(item.title)
values.merge!({
“amount_#{index+1}” => item.price,
“item_name_#{index+1}” => item.title,
“item_number_#{index+1}” => item_id.id,
“quantity_#{index+1}” => item.quantity
})
end

… it referenced the correct id. Keep in mind, this is a really old
example and was something someone else built.

But, I would check anything in your controller or model that is
referencing name_id instead of name.id and do some troubleshooting in
your rails console since you haven’t setup any test code for yourself.

Interesting Alpha B., it does look like that. Where might I be mis-
referncing the object other than the myproject controller?

Alpha B. you GOT it!! Thanks!! Here was my ‘index’ code before:
<% @projects.each do |projects| %>

<%= link_to projects.name, :controller => 'myproject', :action => 'show', :id => current_user.projects.id %> <%= link_to 'Edit', :controller => 'myproject', :action => 'edit', :id => current_user.projects.id %> <%= link_to 'Delete', projects, :confirm => 'Are you sure?', :method => :delete %> <% end %>

After I changed the :id assignment from ‘current_user.projects.id’ to
just ‘projects.id’ the correct id number was getting assigned (i.e.
the ‘show’ & ‘edit’ references in the ‘view page source’ now matched
the delete index number):

Wash Dawgs Edit <a href="/projects/13" onclick="if (confirm('Are you sure?')) (DELETED EXTRA CODE HERE) </tr> <p>THANKS EVERYONE! THIS NEWBIE GREATLY APPRECIATES YOUR INPUT!!!</p>

2010/1/26 Souschef [email protected]:

Edit <a href="/projects/16" onclick="if (confirm('Are you sure?')) {DELETED EXTRA CODE HERE} </tr> </blockquote> <p>What does the code in your view look like for these?</p> <p>Colin</p>

Alpha B. you GOT it!! Thanks!! Here was my ‘index’ code before:
<% @projects.each do |projects| %>

<%= link_to projects.name, :controller => 'myproject', :action => 'show', :id => current_user.projects.id %> <%= link_to 'Edit', :controller => 'myproject', :action => 'edit', :id => current_user.projects.id %> <%= link_to 'Delete', projects, :confirm => 'Are you sure?', :method => :delete %> <% end %>

After I changed the :id assignment from ‘current_user.projects.id’ to
just ‘projects.id’ the correct id number was getting assigned (i.e.
the ‘show’ & ‘edit’ references in the ‘view page source’ now matched
the delete index number):

Wash Dawgs Edit <a href="/projects/13" onclick="if (confirm('Are you sure?')) (DELETED EXTRA CODE HERE) </tr> <p>THANKS EVERYONE! THIS NEWBIE GREATLY APPRECIATES YOUR INPUT!!!</p>

What does the code in your view look like for these?

Colin

Hi Colin -
I haven’t done anything with the views since my goal is to re-use the
‘project’ views (i.e. use the ‘myprojects’ controller to get the
subset of data (i.e. current_user data) then call the ‘project’ views
with the subset of project data). When I do run the app, I’m getting
the basic rails scaffolding view for the index…
Thanks!

You are welcome.

The next thing you should do is write some tests for this.

Alpha B. you GOT it!! Thanks!! Here was my ‘index’ code before:
<% @projects.each do |projects| %>

<%= link_to projects.name, :controller => 'myproject', :action => 'show', :id => current_user.projects.id %> <%= link_to 'Edit', :controller => 'myproject', :action => 'edit', :id => current_user.projects.id %> <%= link_to 'Delete', projects, :confirm => 'Are you sure?', :method => :delete %> <% end %>

After I changed the :id assignment from ‘current_user.projects.id’ to
just ‘projects.id’ the correct id number was getting assigned (i.e.
the ‘show’ & ‘edit’ references in the ‘view page source’ now matched
the delete index number):

Wash Dawgs Edit <a href="/projects/13" onclick="if (confirm('Are you sure?')) (DELETED EXTRA CODE HERE) </tr> <p>THANKS EVERYONE! THIS NEWBIE GREATLY APPRECIATES YOUR INPUT!!!</p>