How to resolve NoMethodError in ror version 4 - ruby-on-rails

When I clicked on "display your data" link it is showing me the following error.
Error:
NoMethodError in Users#show
Showing C:/Site/new/app/views/users/show.html.erb where line #10 raised:
undefined method `email' for #<User::ActiveRecord_Relation:0x2bd81e8>
My code snippets are given below.
views/users/index.html.erb
<h1>Choose your option</h1>
<%= link_to "Enter your data",users_new_path %>
<%= link_to "Display your data",users_show_path %>
views/users/new.html.erb
<h1>Enter your data here</h1>
<%= form_for #user,:url => {:action => 'create'} do |f| %>
<% if #user.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#user.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #user.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.text_field:name,placeholder:"Enter your name" %><br>
<%= f.email_field:email,placeholder:"Enter your email" %><br>
<%= f.text_field:message,placeholder:"Enter your message"%><br>
<%= f.submit "Submit" %>
<% end %>
views/users/show.html.erb
<h1>Display your data</h1>
<ul>
<li>
<p>
<strong>Name:</strong>
<%= #user.name %>
</p>
<p>
<strong>Email:</strong>
<%= #user.email %>
</p>
<p>
<strong>Message:</strong>
<%= #user.message %>
</p>
</li>
</ul>
<%= link_to "Edit",users_edit_path(:id => t.id) %><%= link_to "Delete",users_delete_path(:id => t.id),data: { confirm: 'Are you sure to delete it ?' } %>
<%= link_to "Back",users_index_path %>
controller/users_controller.rb
class UsersController < ApplicationController
def index
end
def new
#user=User.new
end
def create
#user=User.new(users_params)
if #user.save
flash[:notice]="Your data is saved succesfully"
flash[:color]="valid"
redirect_to :action => 'index'
else
flash[:alert]="You are entering wrong data"
flash[:color]="invalid"
render :new
end
end
def show
#user=User.all
end
def delete
#user=User.find(params[:id])
#user.delete
end
def edit
#edit=User.find(params[:id])
#user=User.new
end
def update
#user=User.find(params[:id])
if #user.update_attributes(update_params)
flash[:notice]="Your data has updated successfully"
flash[:color]="valid"
redirect_to :action => 'index'
else
flash[:alert]="Your data could not update..check it.."
flash[:color]="invalid"
render :edit
end
end
private
def users_params
params.require(:user).permit(:name, :email, :message,pets_attributes: [:name, :email,:message])
end
def update_params
params.require (:user).permit(:name,:email,:message,pets_attributes: [:name,:email,:message])
end
end
model/user.rb
class User < ActiveRecord::Base
has_many :pets
accepts_nested_attributes_for :pets
EMAIL_REGEX = /\A[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}\z/i
validates :name, :presence => true,:length => { :minimum => 5 }
validates :email, :presence => true, :uniqueness => true, :format => EMAIL_REGEX
validates :message, :presence => true
end

You should fix your show action from:
def show
#user = User.all
end
to:
def show
#user = User.find(params[:id])
end

In show action, you have
#user = User.all
which assigns relation with all users to #user variable. That's why you have this error, because you can't query whole relation for email. You should have:
#user = User.find(params[:id])
User.find(params[:id]) returns single User instance.

def show
#user=User.all
end
This will return array of users instead of user, so in order to call email on it you have to iterate loop over it.
<% user in #users %> <!-- I have change #user to #users in show method -->
<h1>Display your data</h1>
<ul>
<li>
<p>
<strong>Name:</strong>
<%= user.name %>
</p>
<p>
<strong>Email:</strong>
<%= user.email %>
</p>
<p>
<strong>Message:</strong>
<%= user.message %>
</p>
</li>
</ul>
<%= link_to "Edit",users_edit_path(:id => t.id) %><%= link_to "Delete",users_delete_path(:id => t.id),data: { confirm: 'Are you sure to delete it ?' } %>
<%= link_to "Back",users_index_path %>
<% end %>
Or just change show method
#user = User.find(params[:id])

fix your show action.
replace
#user = User.all
with
#user = User.find(params[:id])

Related

partial won't render in rails

My partial, which is located in views/votes/_voter.html.erb, is not rendering in the browser and not triggering any errors when I place the rendering code in the answers/show.html.erb file. I've already combed through all of the questions and answers related to partials in rails on SO, and can't find anything exactly related to what is happening here. If anyone can help shed any light on the problem, I'd really appreciate it!
answers/show.html.erb file:
<p id="notice"><%= notice %></p>
<%= render partial: 'votes/voter', locals: { answer: #answer } %>
<p>
<strong>Body:</strong>
<%= #answer.body %>
</p>
<%= link_to 'Edit', edit_answer_path(#answer) %> |
<%= link_to 'Back', answers_path %>
views/votes/_voter.html.erb file:
<% if policy( Vote.new ).create? %>
<div class="vote-arrows pull-left">
<div>
<%= link_to " ",
post_up_vote_path(answer),
class: "glyphicon glyphicon-chevron-up #{(current_user.voted(answer) && current_user.voted(answer).up_vote?) ? 'voted' : '' }", method: :post %>
</div>
<div>
<strong><%= answer.points %></strong>
</div>
<div>
<%= link_to " ",
post_down_vote_path(answer),
class: "glyphicon glyphicon-chevron-down #{(current_user.voted(answer) && current_user.voted(answer).down_vote?) ? 'voted' : '' }" , method: :post%>
</div>
</div>
<% end %>
votes_controller.rb:
class VotesController < ApplicationController
before_action :load_answer_and_vote
def up_vote
if #vote
#vote.update_attribute(:value, 1)
else
#vote = current_user.votes.create(value: 1, answer: #answer)
end
redirect_to :back
end
def down_vote
if #vote
#vote.update_attribute(:value, -1)
else
#vote = current_user.votes.create(value: -1, answer: #answer)
end
redirect_to :back
end
private
def load_answer_and_vote
#question = Question.find(params[:question_id])
#vote = #question.votes.where(user_id: current_user.id).first
end
def update_vote(new_value)
if #vote
authorize #vote, :update?
#vote.update_attribute(:value, new_value)
else
#vote = current_user.votes.build(value: new_value, answer: #answer)
authorize #vote, :create?
#vote.save
end
end
end
vote.rb model:
class Vote < ActiveRecord::Base
belongs_to :user
belongs_to :answer, dependent: :destroy
default_scope { order('created_at DESC') }
validates :user, presence: true
validates :answer, presence: true
validates :value, inclusion: { in: [-1, 1], message: "%{value} is not a valid vote." }
after_save :update_answer
def up_vote?
value == 1
end
def down_vote?
value == -1
end
private
def update_post
answer.update_rank
end
end
routes.rb
Languagecheck::Application.routes.draw do
devise_for :users
resources :users
resources :languages do
resources :questions, except: [:index] do
resources :answers
post '/up-vote' => 'votes#up_vote', as: :up_vote
post '/down-vote' => 'votes#down_vote', as: :down_vote
end
end
resources :questions, only: [:index, :new, :create]
get 'about' => 'welcome#about'
root to: 'welcome#index'
end
It looks like you need to be signed in to view the partial.
<% if policy( Vote.new ).create? %>
Do you need to be signed in to vote? Are you signed in? If you are not you wouldn't see this partial.
The other place to check is your vote authorization policies to ensure they are set up correctly.
It turned out that I needed to render the partial in the views/questions/show.html file. Here is what I did to get the desired outcome:
<h3>Question</h3>
<div class="row">
<div class="col-md-8">
<p><%= #question.body %></p>
<small>
<%= image_tag(#question.user.avatar.tiny.url) if #question.user.avatar? %>
submitted <%= time_ago_in_words(#question.created_at) %> ago by
<%= #question.user.name %>
</small>
</div>
<div class="col-md-4">
<% if policy(#question).edit? %>
<%= link_to "Edit Question", edit_language_question_path(#language, #question), class: 'btn btn-success' %>
<% end %>
</div>
</div>
<br/>
<h3>Answers</h3>
<% #question.answers.each do |answer| %>
<%= render partial: 'votes/voter', locals: { answer: #answer } %>
<div>
<h3>
<%= pluralize(#answer.points, 'point') %>
</h3>
<small>
<%= pluralize(#answer.up_votes, 'up vote') %>
<%= pluralize(#answer.down_votes, 'down vote') %>
</small>
</div>
<%= simple_format answer.body %>
<small>
<%= image_tag(answer.user.avatar.tiny.url) if answer.user.avatar? %>
submitted <%= time_ago_in_words(answer.created_at) %> ago by
<%= answer.user.name %>
</small>
<% end %>
<br/>
<h4>Add an Answer</h4>
<%= render "answers/form" %>

param is missing or the value is empty: credit_card(ror_ecommerce)

Getting the error below. I understand what the issue is, but not sure how to fix it?
when i add credit card it says parameter is empty.
I thought I had set everything right, but I hope someone can help me find what I am doing wrong or missing, thanks!
I am getting this error:
param is missing or the value is empty::credit_card
controller:
class Myaccount::CreditCardsController < Myaccount::BaseController
def index
#credit_cards = current_user.payment_profiles
end
def show
#credit_card = current_user.payment_profiles.find(params[:id])
end
def new
#credit_card = current_user.payment_profiles.new
end
def create
#credit_card = current_user.payment_profiles.new(allowed_params)
if #credit_card.save
flash[:notice] = "Successfully created credit card."
redirect_to myaccount_credit_card_url(#credit_card)
else
render :action => 'new'
end
end
def edit
#credit_card = current_user.payment_profiles.find(params[:id])
end
def update
#credit_card = current_user.payment_profiles.find(params[:id])
if #credit_card.update_attributes(allowed_params)
flash[:notice] = "Successfully updated credit card."
redirect_to myaccount_credit_card_url(#credit_card)
else
render :action => 'edit'
end
end
def destroy
#credit_card = current_user.payment_profiles.find(params[:id])
#credit_card.inactivate!
flash[:notice] = "Successfully destroyed credit card."
redirect_to myaccount_credit_cards_url
end
private
def allowed_params
#params.require(:payment_profile).permit!
params.require(:credit_card).permit(:address_id, :month, :year, :cc_type, :first_name, :last_name, :card_name)
end
def selected_myaccount_tab(tab)
tab == 'credit_cards'
end
end
view: _form.html.erb
<% if #credit_card.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#credit_card.errors.count, "error") %> prohibited this credit_card from being saved:</h2>
<ul>
<% #credit_card.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
Please implement me!<br/>
<div class="field">
<%= f.label :name %>
<%= f.text_field :name %>
</div>
<div class="actions">
<%= f.submit %>
</div>
new.html.erb:
<div class='nine large-9 columns'>
<h3> New Credit Card </h3>
<%= form_for(#credit_card, :url => myaccount_credit_cards_path(#credit_card)) do |f| %>
<%= render :partial => 'form', :locals => {:f => f} %>
<% end %>
<%= link_to 'Back to List', myaccount_credit_cards_path, :class => 'button' %>
</div>

Displaying specific info to a logged in user

I am creating a customer service web app for our clients that allows them to submit new customer service tickets, once logged in. I have a login system that I created using the sorcery gem, and I have modified it to accept an additional field: client code.
We are assigning client codes to help prevent unauthorized users from creating accounts.
Upon login, it asks for the information like so:
Name:
Email:
Client Code: (we assign this)
Password:
My question is this, is there a way to only display customer service tickets to clients with the same client code? For example, The "Coca-Cola" clients would only see other "Coca-Cola" tickets and the "Pepsi" clients would only see other "Pepsi" tickets, etc.
Here is my Tickets Controller:
class TicketsController < ApplicationController
before_filter :require_login
def new
#ticket = Ticket.new
end
def create
#ticket = Ticket.new(ticket_params)
if
#ticket.save
redirect_to #ticket
flash[:notice] = "Your Ticket has been submitted. We will contact you very soon!"
else
flash[:notice] = "Something went wrong :("
render 'new'
end
end
def show
#ticket = Ticket.find(params[:id])
end
def index
#tickets = Ticket.all
end
def edit
#ticket = Ticket.find(params[:id])
end
def update
#ticket = Ticket.find(params[:id])
if #ticket.update(ticket_params)
redirect_to #ticket
else
render 'edit'
end
end
def destroy
#ticket = Ticket.find(params[:id])
#ticket.destroy
redirect_to tickets_path
end
private
def ticket_params
params.require(:ticket).permit(:name, :email, :phone, :help)
end
end
Here is the Ticket Index View:
<div class="panel panel-default">
<div class="panel-heading">Ticket Queue</div>
<div class="panel-body">
<table class="table">
<tr>
<th>Name</th>
<th>Phone</th>
<th></th>
<th></th>
</tr>
<% #tickets.each do |ticket| %>
<tr>
<td><%= ticket.name %></td>
<td><%= ticket.phone %></td>
<td><%= button_to "View or Edit", ticket_path(ticket), :class => "btn btn-primary btn-sm", :method => :get %></td>
<td><%= button_to "Delete", ticket_path(ticket), :class => "btn btn-primary btn- sm", :method => :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
</div>
Here is the New Ticket View:
<div class="panel panel-info">
<div class="panel-heading">
<div id="wrapper">
<h1 class="panel-title">New Ticket
<div id="first"><%= button_to "Back", root_path, :class => "btn btn-primary btn-sm", :method => :get %></div>
</div>
</h1>
</div>
<div class="panel-body">
<%= form_for :ticket, url: tickets_path do |f| %>
<p>
<%= f.label "Name:" %>
<%= f.text_field :name %>
</p>
<p>
<%= f.label "Email:" %>
<%= f.text_field :email %>
</p>
<p>
<%= f.label :"Phone #:" %>
<%= f.text_field :phone %>
</p>
<p>
<%= f.label :"How can we help?" %>
<p><%= f.text_area :help, :cols=> 38, :rows => 8 %></p>
</p>
<p>
<button type="submit" class="btn btn-primary btn-sm"><span class="glyphicon glyphicon-envelope"></span> Submit Ticket</button>
</p>
<% end %>
</div>
</div>
Here is the User Model:
class User < ActiveRecord::Base
authenticates_with_sorcery!
validates :password, length: { minimum: 3 }
validates :password, confirmation: true
validates :password_confirmation, presence: true
validates :code, inclusion: { in: %w(Client1, Client2), message: "Please enter a valid Client Code", :allow_nil => false}
validates :email, uniqueness: true
validates_format_of :email, :with => /\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
end
Here is the New User View:
<%= form_for(#user) do |f| %>
<% if #user.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#user.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% #user.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :email %><br>
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :password %><br />
<%= f.password_field :password %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %>
</div>
<div class="field">
<%= f.label "Client Code" %><br />
<%= f.text_field :code %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Here is the User Controller:
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
skip_before_filter :require_login, only: [:index, :new, :create]
# GET /users
def index
#users = User.all
end
# GET /users/1
def show
end
# GET /users/new
def new
#user = User.new
end
# GET /users/1/edit
def edit
end
# POST /users
def create
#user = User.new(user_params)
if #user.save
redirect_to(:users, notice: 'User was successfully created')
else
render :new
end
end
# PATCH/PUT /users/1
def update
if #user.update(user_params)
redirect_to #user, notice: 'User was successfully updated.'
else
render :edit
end
end
# DELETE /users/1
def destroy
#user.destroy
redirect_to users_url, notice: 'User was successfully destroyed.'
end
private
# Use callbacks to share common setup or constraints between actions.
def set_user
#user = User.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def user_params
params.require(:user).permit(:email, :password, :password_confirmation, :code)
end
end
Let me know if you need to see anything else, thank you!
From your example, I would think Users would have an additional database layer:
class User < ActiveRecord::Base
belongs_to :company
has_many :tickets, through: :companies
end
class Company < ActiveRecord::Base
has_many :users
has_many :tickets
end
class Ticket < ActiveRecord::Base
belongs_to :company
end
Then you can easily display tickets associated with each company

How to make the error messages form only appear when actual error messages are generated

I'm following the RailsSpace tutorial. My error form is being displayed always. It's always on! I don't know how to make it go away. I know that using #user.errors.clear will actually clear the messages. I tried using it in the view but no error messages will display at all. I appreciate your help.
Here is the error form code:
<% if #user.errors.any? %>
<div id="errorExplanation">
<h2>Please fix the following <%= pluralize(#user.errors.count, "error") %>:</h2>
<ul>
<% #user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
Here is my controller:
class UserController < ApplicationController
def index
#title = "NubeMart Hub!"
end
def register
#user = User.new
#title = "Register"
if request.post?
#user = User.create(ad_params)
end
if #user.save
flash[:notice]="User #{#user.screen_name} created!"
redirect_to :action=>"index"
end
end
def ad_params
params.require(:user).permit(:screen_name, :email, :password)
end
end
And here is my view:
<h2>Register</h2>
<%= form_for :user do |form| %>
<%= render "shared/form_errors", :user => #user %>
<fieldset>
<legend>Enter Your Details</legend>
<div class="form_row">
<label for="screen_name">Screen name:</label>
<%= form.text_field :screen_name,
:size => User::SCREEN_NAME_SIZE,
:maxlength => User::SCREEN_NAME_MAX_LENGTH %>
</div>
<div class="form_row">
<label for="email">Email:</label>
<%= form.text_field :email,
:size => User::EMAIL_SIZE,
:maxlength => User::EMAIL_MAX_LENGTH %>
</div>
<div class="form_row">
<label for="password">Password:</label>
<%= form.password_field :password,
:size => User::PASSWORD_SIZE,
:maxlength => User::PASSWORD_MAX_LENGTH %>
</div>
<div class="form_row">
<%= submit_tag "Register!", :class => "submit" %>
</div>
</fieldset>
<% end %>
Your register method is wrong:
def register
#user = User.new
#title = "Register"
if request.post?
#user = User.create(ad_params)
end
if #user.save # <== This block should be moved!
flash[:notice]="User #{#user.screen_name} created!"
redirect_to :action=>"index"
end
end
This code if #user.save will execute even if the request isn't post. You have put this code outside of if block if request.post?.
I think the below code should solve your issue.
def register
#title = "Register"
if request.post?
#user = User.new(ad_params) # I have changed create to new
if #user.save # here your user will be saved(inly in case of post request)
flash[:notice]="User #{#user.screen_name} created!"
end
else
#user = User.new # (this is when request is not post)
end
redirect_to :action=>"index"
end

How to create a instance of a model if .find returns nil

I am attempting to use a text field to search for a user email and if it is found, create a membership. if it is not found i would like to create the user based on the email address.
memberships/Index.html.erb
<%= render :partial => 'shared/logedinNav' %>
<section class="centered">
<header>Team Settings</header>
<section class="main">
<aside class="blue_nav_aside">
<nav>
<ul>
<li><%= link_to_unless_current "General", team_info_path(:id => #team.id) %></li>
<li id="bluenav"><%= link_to_unless_current "Team Members", memberships_path(:id => #team.id) %></li>
<li><%= link_to_unless_current "Tags & Categories", %></li>
<li><%= link_to_unless_current "Payments", %></li>
</ul>
</nav>
</aside>
<section class="inline_form">
<%= form_for #membership do |u|%>
<% if notice %>
<p id="notice"><%= notice %></p>
<% end %>
<% if alert %>
<p id="alert"><%= alert %></p>
<% end %>
<%= render "shared/error_messages", :target => #membership %>
<%= u.hidden_field :team_id, :value => #team.id %>
<h1><span class="pictos pictos-form-h1">g</span>Team Members</h1>
<%= u.text_field :user_email, :placeholder => " To add a team member, enter their email here..." %>
<%= u.submit "Invite", :class => "grey button" %>
<section>
<ul>
<% #memberships.each do |m|%>
<li>
<%= m.user.email %>
<% if m.team.admin_user_id != m.user_id %>
<%= link_to(membership_path(m), :confirm => 'Are you sure you want to delete this video?', :method => :delete, :class => "red_link") do %>
<span class="pictos pictos-remove">-</span> Remove
<% end %>
<% end %>
</li>
<% end %>
</ul>
</section>
<% end %>
</section>
</section>
Memberships_controller.rb
class MembershipsController < ApplicationController
def index
#team = Team.find(params[:id])
#memberships = Membership.where(:team_id => #team.id)
#membership = Membership.new
end
def create
#membership = Membership.new(params[:membership])
#team = Team.find(params[:membership][:team_id])
#membership.user = User.find_or_create_by_email(:email => params[:membership][:user_email], :password => "pass", :password_confirmation => "pass")
if #membership.save
redirect_to memberships_path(:id => #team.id), :notice => "New membership created."
else
redirect_to memberships_path(:id => #team.id), :alert => "Fail."
end
end
....
end
Membership.rb
class Membership < ActiveRecord::Base
belongs_to :team
belongs_to :user
accepts_nested_attributes_for :user
attr_accessible :user_id, :team_id
attr_accessor :user_email
validates_presence_of :user_id, on: :create
after_create :set_team_admin
def set_team_admin
self.team.set_admin_user
end
end
it works when the user is found but right now its not recognizing the create_user at all and skips to the Fail redirect.
UPDATE: this is the updated code with suggestions mentioned below.
The problem is that your membership instance doesn't know about the user_email parameter.
you could be using the rails dynamic finder methods http://api.rubyonrails.org/classes/ActiveRecord/Base.html#label-Dynamic+attribute-based+finders for creating a user?
e.g. in memberships_controller.rb
def create
#membership = Membership.new(params[:membership])
#membership.user = User.find_or_create_by_email(params[:membership][:user_email])
if #membership.save
redirect_to memberships_path(:id => #team.id), :notice => "New membership created."
else
redirect_to memberships_path(:id => #team.id), :alert => "Fail."
end
end

Resources