in my rails 4 app, i have a user model that has_one profile model which also belongs_to the user model
this is my first time using a nested resource so im kinda lost to it
here how it goes
, a user creates an account,after succesful email authentication , user proceed to create a profile. Problem is, im getting error on using the build_association. Im not sure whether the problem is actually that or im getting null values on the params(which i think not)
in my routes.rb
resources :users do
resources :profiles
end
profiles view, new.html.erb
<%= form_for(#profile,url:{ :controller => 'profiles', :action => 'create'},html: {class: "ui large segment form error"}) do |f| %>
<%= render 'shared/form_error_messages', object: f.object%>
<div class="ui horizontal divider">Create a Profile</div>
<%= f.text_field :first_name, :placeholder => "First Name" , :required => true%>
<%= f.submit "Submit Profile", class: "ui submit button"%>
<% end %>
profiles_controller.rb
def new
#user = User.find(params[:user_id])
#profile = #user.build_profile
end
def create
#profile = #user.build_profile(profile_params)
if #profile.save
flash[:success] = "Profile has been created"
redirect_to root_url
else
render 'new'
end
end
private
def profile_params
params.require(:profile).permit(:first_name)
end
when im submitting the form, im getting
NoMethodError in ProfilesController#create
undefined method `build_profile' for nil:NilClass
Application Trace | Framework Trace | Full Trace
app/controllers/profiles_controller.rb:9:in `create'
Request
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"MFCANYra..",
"profile"=>{"first_name"=>"sample",
"commit"=>"Submit Profile",
"user_id"=>"1"}
Try changing the create action in profiles_controller.rb as below :-
def create
#user = User.find(params[:profile][:user_id])
#profile = #user.build_profile(profile_params)
if #profile.save
flash[:success] = "Profile has been created"
redirect_to root_url
else
render 'new'
end
end
let me know this worked or not, try to find if something else is causing the problem, thanks.
Related
Whenever I try to delete a user I get the error: Couldn't find User with 'id'=8. The error points to a line from application_controller.rb in the "current_user" method: ActiveRecord::RecordNotFound at /users. "/users" is where I'm trying to redirect_to.
I don't know where I'm going wrong. I wonder if it's a <%= javascript_include_tag ... %> that I'm missing in the application.html.erb file.
application_controller.rb
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
users_controller.rb
def delete
#user = User.find(params[:id])
end
def destroy
#user = User.find(params[:id]).destroy
flash[:warning] = '#{#user.name} has been deleted.'
redirect_to users_path
end
sessions_controller.rb
class SessionsController < ApplicationController
def create
user = User.find_by(email: params[:email])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
if request.referrer == login_url
redirect_to root_path
else
redirect_to :back
end
else
flash.now[:danger] = "Email and password did not match. Please try again."
render :new
end
end
def destroy
session[:user_id] = nil
flash[:success] = "Logged out."
redirect_to :back
end
end
views/users/show.html.erb
<p id="notice"><%= notice %></p>
<h2 id="page-title"><%= #user.name %> <small>#<%= #user.username %></small>
<div class="small pull-right"></div>
</h2>
<hr/>
<% #user.types.each do |type| %>
<h4><small><%= type.name %></small></h4>
<% end %>
<% if current_user == #user %> # visible to current_user
<div class="float-right">
<%= link_to 'Edit', edit_user_path(#user), class: 'btn btn-default' %>
<%= link_to 'Delete Account', user_path,
data: { confirm: 'Are you sure you want to delete your account forever?' },
method: :delete, class: 'btn btn-danger' %>
</div>
<% end %>
If you need anymore files let me know.
I feel like this is a simple fix. Please help. And thank you in advance!
When you use find with a non existing record id, ActiveRecord throws ActiveRecord::RecordNotFound exception. You can get around this by usingfind_by, which will return nil. so try this in your application_controller.rb
def current_user
#current_user ||= User.find_by(id: session[:user_id])
end
Or you can just use your check more correctly by doing this
def current_user
#current_user ||= (session[:user_id].present? && User.find(session[:user_id]))
end
The second will still raise exception if the user_id in the session is not an invalid user.
Hope that helps
I guess if bug is in application controller add the following code in the destroy method of user controller:
session[:user_id] = nil if current_user == #user
This way if you delete the current connected user, it'll be logged out.
I am trying to show a form on the contact page, but it is from another controller.
The current code results in "First argument in form cannot contain nil or be empty"
After searching it looks there is a problem with the local hash that is not passed.
How can I correctly pass the locals with this code so that it works?
inquiries_controller.rb
class InquiriesController < ApplicationController
def new
#inquiry = Inquiry.new
end
def create
#inquiry = Inquiry.new(params[:inquiry])
if #inquiry.deliver
render :thank_you
else
render :new
end
end
end
inquiries_form.html.erb
<%= form_for #inquiry do |f|
f.text_field :name
f.text_field :email
f.text_area :message
f.submit "Send"
end %>
static_pages\contact.html.erb
<%= render "inquiries/form",
:inquiry => #inquiry %>
HI try adding this to your StaticPages Controller
class StaticPagesController < ApplicationController
def contact
#inquiry = Inquiry.new
end
end
Its a very common mistake. Also I believe your form may also be wrong unless you are using a gem that allows for that type of form. Let me know if this will fix your error.
I am working on a rails application and want to send an email with an inline image to the email address that the user enters. I have been struggling to do it. I checked online and this is what I did.
When I enter an email in development it gives me an error saying,
ActionController::UnknownFormat
This is my ActionMailer Notifier.rb
class Notifier < ActionMailer::Base
default from: "insidespintex#gmail.com"
def enter_email(sending)
#coming = sending
attachments.inline['blank'] = {
:data => File.read("#{Rails.root.to_s + '/app/assets/images/News.png'}"),
:mime_type => "image/png",
:encoding => "base64"
}
mail :to => #coming.email, :subject => 'InsideSpintex is coming soon'
end
end
This is my ApplicationController LandingController.rb
class LandingController < ApplicationController
layout 'landingPage'
def soon
#coming = Coming.new
end
def after
render 'after'
end
def save_email
#coming = Coming.new(soon_params)
respond_to do |format|
if #coming.save
Notifier.enter_email(#coming).deliver
format.html { render action: 'after' }
#render 'after'
else
render 'soon'
end
end
end
#render 'soon'
private
def soon_params
params.require(:coming).permit(:email)
end
end
And this is my View enter_email.html.erb
<p> Hello There,</h3>
<%= image_tag attachments['News.png'] %>
Well, I think that you don't need the encoding part in your attachments.inline hash. I was using something like this on a project:
Mailer method:
attachments.inline['logo.png'] = {
data: File.read(Rails.root.join('app/assets/images/logo.png')),
mime_type: 'image/png'
}
and you are missing the .url in the view:
<%= image_tag attachments['logo.png'].url %>
Currently my application is using devise and my users are required to enter a password when updating their profile.
I am working on implementing an additional field to my user's table which remembers their sidebar navigational preference (expanded or collapsed). For testing, I setup a boolean field called "menu_collapsed" which is set to "false" by default.
I am trying to have this value updated to "true" remotely when the user decides to condense the sidebar menu.
Index
<li><%= link_to('Toggle', toggle_menu_preference_user_path(#user), :method => :put) %></li>
Routes
resources :users do
member { put :toggle_menu_preference }
end
Users Controller
def toggle_menu_preference
#user = current_user
#user.menu_collapsed = !#user.menu_collapsed
#user.save
end
Application Controller
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:first_name, :last_name, :email, :account_id, :account_name, :password, :password_confirmation) }
devise_parameter_sanitizer.for(:account_update).concat([:name])
end
When I click on the link, it will process the request but I hit a wall with Devise wanting the user to include their password.
Is there a way to by pass the requirement for a password just for this user attribute?
This seems to work like a charm!
Tested on local host as well as Heroku
Application Controller (added :menu_collapsed) to sanitizer
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:first_name, :last_name, :email, :account_id, :account_name, :password, :password_confirmation) }
devise_parameter_sanitizer.for(:account_update).concat([:name, :menu_collapsed])
end
Routes
resources :users do
member { put :toggle_menu_preference }
end
User Controller
def menu_preference
#user = current_user
#user.menu_collapsed = !#user.menu_collapsed
#user.save
if #user.menu_collapsed
render :nothing => true
else
render :nothing => true
end
end
View
<%= link_to menu_preference_user_path(current_user), id: "layout-condensed-toggle", remote: true do %>
<div class="iconset top-menu-toggle-dark"></div>
<% end %>
Hello there i have been having problems trying to get my Name added onto my index.html via the new.html using form_for kindly look into the code below and correct my code please
My controller
def new
#post = Name.new
end
def create
#post = Name.new(post_params)
if #post.save
redirect_to names_path, notice: "your name was added"
else
render "new"
end
end
def post_param
params.require(:post).permit(:name)
end
My new.html.erb
<h1> Add your name </h1>
<%= form_for #post do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.submit "Add your name" %>
<% end %>
I am having trouble in this lower part when i click the f.submit (the button that appears in the htlm) it throws me the error.
Your new and create methods should look like this
def new
#post = Post.new #here
end
def create
#post = Post.new(post_params) #here
if #post.save
redirect_to names_path, notice: "your name was added"
else
render "new"
end
end
You are confused of using attribute names with model name.You should be looking at these Guides.It should help you.
Update
As you said you created a Name model,you shouldn't be creating an attribute which is same as your model name.
Solution
Either change your attribute name or model name to some other meaningful name.