uninitialized constant ProfilesController - ruby-on-rails-3

I have an error "uninitialized constant ProfilesController" on my Profiles controller. This is the profiles_controller.rb:
class ProfilesController < ApplicationController
def new
#profile = Profile.new
end
def create
#profile = Profile.new(params[:profile])
if #profile.save
redirect_to profile_path, notice: I18n.t('.profile.created')
else
render action: "new"
end
end
end
This is the routes.rb:
resources :profiles, only: [:new, :create]
And this the output of rake routes:
profiles POST /profiles(.:format) profiles#create
new_profile GET /profiles/new(.:format) profiles#new
When I click a link for "new_profile_path" I get the error, but to me everything seems OK? The controller name is plural,the routes are OK?

You most likely spelled your controller file wrong. Confirm that file is truly: `/app/controllers/profiles_controller.rb'

Really strange, I created a Books controller with a generator, renamed everything to Profiles and then it works as normal. As far as I can see the routes are identical. Strange....

I had the same problem when i checked the name of the controller was 'profile_controller.rb'(i had created it manually though). but inside the definition it was "ProfilesController".
class ProfilesController < ApplicationController
def index
end
def new
#profile = Profile.new
end
def create
end
end
So if your controller name is correct and you have added the route("resources :profiles") then it will work as expected

Related

Ruby on Rails : Redirect path after sign_up devise

I am using gem devise. And I overrided devise registrations controller and everything went great, but the problem is redirect path after it is saved. What I want to do is after user saved, it redirects to profile_path, but what I have now is user need to sign in before it redirect to profile path. How can I solve that?
Here is my register controller:
class RegistrationsController < Devise::RegistrationsController
def new
super
end
def create
#user= User.new(params[:user])
if #user.save
redirect_to profile_path, notice: 'User was successfully created.'
else
render action: "new"
end
end
def update
super
end
end
And this is my application controller which control the path after sign up and sign in:
class ApplicationController < ActionController::Base
protect_from_forgery
def after_sign_in_path_for(resource)
if request.path !~ /^\/admins\//i
resource.sign_in_count <= 1 ? '/profile' : root_path
end
end
end
Before I override the register controller, redirect after sign up went great. Would be really glad if anyone could help. Thanks.
You have to sign the user in in your create method:
if #user.save
sign_in(resource_name, resource)
current_user = #user # !! now logged in
redirect_to profile_path, notice: 'User was successfully created.'
else
You can look at the original create method in Devise::RegistrationsController to see how this works.

Rails - Show Action & View for models with one-to-one association?

I have a simple app with a User model & an Instructor_Profile model. The associations between these two models is one-to-one. I cannot get my view show.html.erb to render. I am simply trying to display a single attribute from the Instructor_Profile model and I get this error:
NoMethodError in Instructor_profiles#show
undefined method `name' for nil:NilClass
Any help would be greatly appreciated!
Models:
class User
has_one :instructor_profile
class InstructorProfile
belongs_to :user
UsersController:
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
UserMailer.welcome_email(#user).deliver
render 'static_pages/congratulations'
else
render 'new'
end
end
InstructorProfilesController:
def new
#instructor_profile = current_user.build_instructor_profile
end
def create
#instructor_profile = current_user.build_instructor_profile(params[:instructor_profile])
if #instructor_profile.save
flash[:success] = "Profile created!"
redirect_to root_path
else
....
end
end
def show
#user = User.find(params[:id])
#instructor_profile = #user.instructor_profile
end
Views/instructor_profiles/show.html.erb:
<p>Display Name: <%= #user.instructor_profile.name %></p>
It happens because #user.instructor_profile is nil.
That means there is no instructor_profile corresponding to the #user.
Please check the create method inside the UserController to confirm whether instructor_profile is creating or not. Code should be something like this,
#user.instructor_profile = InstructorProfile.new(name: "my_name")
#user.instructor_profile.save
edited:
has_one association doesn't mean that every user has to have an instructor_profile. So before you call the #user.instructor_profile.name, just confirm that #user have instructor_profile or not. In your view, you can easily solve this error by adding one condition..
<p>Display Name: <%= #user.instructor_profile ? #user.instructor_profile.name : "no instructor_profile present" %></p>.
One more thing, in instructor_profiles_controller/show, change the code into
#instructor_profile = InstructorProfile.find(params[:id])
#user = #instructor_profile.user

Rails 3 recursive polymorphic comments model, how to do redirect to top-most parent

I'm still earning my stripes in Rails and have ran into a problem I can use some help on. I'm building an app that has various models (stories, photos, artwork, etc.) that a user can comment on, as well as the comments themselves. I have 98-99% of the functionality working but am stuck on getting the redirect to redirect to the top-most parent (a story, photo, etc.) after the comment has been created.
My comment model look like this:
# /app/models/comment.rb
class Comment < ActiveRecord::Base
belongs_to :commentable, :polymorphic => true
has_many :comments, :as => :commentable
end
...I have several models that a user can comment on, for example a story model:
# /app/models/story.rb
class Story < ActiveRecord::Base
has_many :comments, :as => :commentable
end
My comments controller looks like this at this point:
# /app/controllers/comments_controller.rb
class CommentsController < ApplicationController
def index
#commentable = find_commentable
#comments = #commentable.comments
end
def new
#commentable = find_commentable
end
def create
#commentable = find_commentable
#comment = #commentable.comments.build(params[:comment])
if #comment.save
redirect_to :back
else
render :action => 'new'
end
end
protected
def find_commentable
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
nil
end
end
...And of course my routes look like this:
# /config/routes.rb
resources :comments do
resources :comments
end
resources :stories do
resources :comments
end
The particular line I need to change is the redirect_to :back line (everything else, the polymorphism, the recursion of comments, etc. works fine). The current code works as intended when a user is commenting on a story but it's not ideal when a user is commenting on a comment because the form for that functionality is not on the story "show" page (perhaps it needs to be?).
What I have tried to do (and what I suspect the solution might be) is a method that finds the parent object and recurses when that object is a comment. My previous attempts at doing this has not been clean at all and I have yet to get a working prototype working.
I used this railscasts episode to base the majority of my code but the redirect_to :id => nil doesn't work for me as the create comment method is somehow called and it results in a NilClass error when it attempts to build comments (perhaps something is wrong with my routing as I don't see how the index action would call create?).
So Rails experts, what am I doing wrong? What do I need to do here to get this working? I feel like I'm 99% there but that last 1% is driving me crazy.
Thanks in advance...
OK i had to read this a couple times...
#comment.commentable
would return an instance of Story or whatever object that did the comment.
Solved this...It's probably not the cleanest but it works:
I first added a method in comments controller...
def get_master
#parent = #comment.commentable
if #parent.respond_to?('commentable_type')
#comment = #parent
get_master
else
return #parent
end
end
Then I changed my redirect_to to call this method in the create controller.
The key was understanding that #object.respond_to? was what I needed to do check if a method is defined.
Here's a full example of how it works: http://t.co/N6WIGzuW

Posting with Nested Resources

I have nested my resources (see below) and when I try to create a new entity, I get the following error. Does anyone know why I'm getting this error and how to solve it?
undefined method `applications' for nil:NilClass
resources careers do
resources applications
end
Within the 'Applications' controller I have:
before_filter [[:authenticate, :except => :new], :load_career]
def create
# The following line is where the error originates
#application = #career.applications.new(params[:application])
respond_to do |format|
...
end
end
private
def load_career
#career = Career.find(params[:career_id])
end
The Career and Application models have has_many :applications and belongs_to :career respectively.
And the '*_create_applications' migration has a career_id field.
I have never seen before_filters defined that way. I just tried it in Rails 3 and it doesn't seem to do anything. I would give each callback it's own before_filter call:
before_filter :authenticate, :except => :new
before_filter :load_career

How do I make a route to a custom controller action in Rails 3?

I'm new to Rails, and a bit confused about routes:
I have a Devices controller:
#devices_controllers.rb
class DevicesController < ApplicationController
def index
#devices = Device.all
end
def show
#device = Device.find(params[:id])
end
def new
#device = Device.new
end
def create
#device = Device.new(params[:device])
if #device.save
flash[:notice] = "Successfully created device."
redirect_to #device
else
render :action => 'new'
end
end
def edit
#device = Device.find(params[:id])
end
def update
#device = Device.find(params[:id])
if #device.update_attributes(params[:device])
flash[:notice] = "Successfully updated device."
redirect_to #device
else
render :action => 'edit'
end
end
def destroy
#device = Device.find(params[:id])
#device.destroy
flash[:notice] = "Successfully destroyed device."
redirect_to devices_url
end
def custom_action
"Success"
end
I'd like to access the "custom_action" action via a url like this:
http://foo.bar/devices/custom_action
I've added this line to my routes.rb file:
match 'devices/custom_action' => 'devices#custom_action'
However, when I try the URL in the browser, I get this error:
ActiveRecord::RecordNotFound in DevicesController#show
Couldn't find Device with ID=custom_action
It seems to be going to #show action instead of #custom_action. If a user id is not supplied, and I go to http://foo.bar/devices/custom_action, I'd like it to go #custom_action.
I've read Rails Routing from the Outside, but still can't still seem to figure out the problem.
I think the problem may be because of the order in which you have defined your routes.
I suspect you have resources :devices in your routes.rb. In addition, I suspect you have defined your custom route after this. If you type rake routes into your console/terminal, you will see that there is already a route defined for the following pattern:
GET /devices/:id
This route is a product of resources :devices, which is taking precedence over your custom route. Referring back to the Edge Guides, specifically in 1.1. Connecting URLs to Code, it states that the request will be dispatched to the first matching route. So a simple fix would be to define your custom route before resources :devices.