My contorller is like this
class FriendController < ApplicationController
def friend_list
#user = User.new
end
def be_mine_friend
#user = params[:user]
if #user.save?
redirect_to friend_mine_friend_url
flash[:notice] = "#{#user[:name]} have been added to my friend list"
else
redirect_to friend_friend_list_path
end
end
def mine_friend
#title = "Details list of Mine Friend"
#friend = #user.paginate(page: params[:page], per_page: 10)
respond_to do |format|
format.html
format.json { render json: #friend }
end
end
end
View page for friend_list
<div class="container">
<%= notice %>
<%#= errors %>
<%= form_for(#user, url: friend_be_mine_frien_path) do |user| %>
<%= user.text_field 'name', placeholder: "Your name Please" %></br>
<%= user.text_field 'email', placeholder: "Your Email Please" %></br>
<%= user.text_field 'address', placeholder: "Your Address Please" %></br>
<%= user.submit "Be Mine Friend", class: "btn btn-primary" %>
<% end %>
</div>
view page for mine_friend
<div class="container">
<p><strong><%= #title %></strong><p>
<%= notice %>
<%= will_paginate #friend, previous_label: "<<", next_label: ">>", class: "pagination pagination-large" %>
<table class="table table table-striped">
<tr>
<th>Name</th>
<th>Address</th>
<th>Email</th>
</tr>
<% #friend.each do |friend| %>
<tr>
<td><%= friend.name %></td>
<td><%= friend.address %></td>
<td><%= friend.email %></td>
</tr>
<% end %>
</table>
</div>
and model is
class User < ActiveRecord::Base
attr_accessible :address, :email, :message, :name
validates :address, :email, :message, :name, presence: :true
end
I while I try to save user from friend_list I get such
Processing by FriendController#be_mine_friend as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"5A1dXtuYJpfqpOphkdl+WA657T3ok2zu/8U1v1B8tEg=", "user"=>{"name"=>"Amritdeep", "email"=>"amritdeepdhungana#hotmail.com", "address"=>"Bou"}, "commit"=>"Be Mine Friend"}
Completed 500 Internal Server Error in 1ms6090>:
the error is
NoMethodError - undefined method `save?' for #<ActiveSupport::HashWithIndifferentAccess:0x00000003c06090>:
What should I do now? Do you guys have any solution for it? I don't know why this ActiveSupport::HashWithIndifferentAccess error is following. Do you guys have any idea about it?
#user = params[:user]
if #user.save?
The params[:user] is a hash. it is not a user object. This is the norm:
#user = User.create(params[:user])
Related
I am using rails gem 'best_in_place' and data edit one by one, as clicked perticular field.
how can i active all fields for editable onclick update/edit button?
def update
if m_user[:name].present?
MUser.where(:id => id).update(:name => m_user[:name])
elsif m_user[:gender].present?
MUser.where(:id => id).update(:gender => m_user[:gender])
else
flash[:danger] = 'not updated'
end
end
View code:
<% #user.each do |record| %>
<tr>
<td>
<%= best_in_place record, :name, :as => :input %>
</td>
<td>
<%= best_in_place record, :gender, :as => :select, collection: (MUser.pluck(:id,:gender)) %>
</td>
<%= best_in_place record, :dob, :as => :date, class: 'datepicker1 %>
</td>
</tr>
<% end %>
<%= submit_tag('update',:name => 'update_data', class: 'btn btn-primary btn-sm', :id => 'update_btn') %>
Now data edit like if i edit name it will automatically editable
,but how can I edit when i clicked update/edit button then make all fields active for edit.
As we discussed, you need to do a couple of changes
Add a _user.html.erb partial to render the records with below code.
<td>
<%= user.name %>
</td>
<td>
<%= user.gender %>
</td>
<td>
<%= user.dob %>
</td>
<td>
<%= link_to "Edit", edit_user_path(user), remote: true %>
<td>
Now change your index.html.erb code like below.
<% #users.each do |user| %>
<tr id="record-row-<%= user.id %>">
<%= render prtial: 'user', locals: { user: user } %>
</tr>
<% end %>
Now refresh your page and you will see the User records in table rows.
Add a new partial _user_form.html.erb to render the form and add below code in it.
<td colspan="4">
<%= form_for(#user, remote: true) do |f|
<table>
<tbody>
<tr>
<td><%= f.text_field :name, class: 'form-control' %></td>
<td><%= f.select :gender, MUser.pluck(:gender, :id).uniq, { selected: #user.gender }, class: 'form-control' %></td>
<td><%= f.text_field :name, class: 'form-control datepicker1' %></td>
<td><%= f.submit "Update" %></td>
</tr>
</tbody>
</table>
<% end %>
</td>
Now need to update edit and update actions.
edit action
def edit
#user = User.find(params[:id])
respond_to do |format|
format.js { }
format.html { render 'edit' }
end
end
update action
def update
#user = User.find(params[:id])
respond_to do |format|
if #user.update_attributes(user_params)
format.js { }
format.html { redirect_to #user, notice: 'User was updated successfully.' }
else
format.js { }
format.html { render 'edit' }
end
end
end
private
def user_params
params.require(:user).permit(:name, :gender, :dob)
end
Now you need to create an edit.js.erb file to render the form on selected row.
$("#record-row-<%= #user.id %>").html("<%= escape_javascript(render 'user_form') %>")
And you also need an update.js.erb file to update the table row after updating the user record.
$("#record-row-<%= #user.id %>").html("<%= escape_javascript(render partial: 'user', locals: { user: #user } ) %>")
Now all set. Refresh your page and click on Edit button of a row. A form will appear. Change the value and click on Update button. You will see the updated record.
Let me know if you have nay issues. Happy to help.
I'm trying to add a search bar for a database website I created, I found a tutorial and I "think" I did it correct.
When I do a search, such as "Judy Zhang", nothing shows up, even though it is in the database
my vendor.rb/concerns/models/app file
class Vendor < ApplicationRecord
has_many :fotos
def self.search(search)
if search
Vendor.where('lower(contact_name) LIKE ?', "'%#{search.downcase}%'")
else
Vendor.all
end
end
end
I believe I didn't do the coding right. Very new to ruby on rails. What did I do wrong here?
code for index.html.erb/vendors/views/layouts/app
<body>
<div class = "head">
<h1>Vendors </h1>
<div class = "image1" >
<img src= "http://dx.deucex.com/i/logo.png" >
</div>
</div>
</body>
<table>
<tr>
<%= button_to "New Vendor", new_vendor_path, :method => "get" %>
<%= button_to "Inventory", inventories_path, :method => "get" %>
<%= form_tag vendors_path, :method => 'get' do %>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
<% end %>
</tr>
</table>
<table>
<tr>
<th>Company</th>
<th>Contact Name</th>
<th>Phone</th>
<th>Email</th>
</tr>
<% for vendor in #vendors %>
<tr>
<td><%= vendor.company %></td>
<td><%= vendor.contact_name %></td>
<td><%= vendor.phone %></td>
<td><%= vendor.email %></td>
<body>
<div class = "button1" >
<td><%= button_to "Show", vendor_path(vendor), :method => "get" %></td>
</div>
</body>
<td><%= button_to "Edit", edit_vendor_path(vendor), :method => "get" %></td>
<div class = "button3">
<td><%= button_to 'Delete',
vendor_path(vendor),
method: :delete,
data: { confirm: 'Are you sure?'} %></td>
</div>
</tr>
<% end %>
</table>
code for my VendorsController.rb/concerns/controller/app
class VendorsController < ApplicationController
def index
#vendors = Vendor.search(params[:search])
end
def show
#vendor = Vendor.find(params[:id])
end
def new
#vendor = Vendor.new
end
def create
#vendor = Vendor.new(vendor_params)
if #vendor.save
redirect_to #vendor
else
render 'new'
end
end
def edit
#vendor = Vendor.find(params[:id])
end
def update
#vendor = Vendor.find(params[:id])
if #vendor.update (vendor_params)
redirect_to #vendor
else
render 'edit'
end
end
def destroy
#vendor = Vendor.find(params[:id])
#vendor.destroy
redirect_to vendors_path
end
end
private
def vendor_params
params.require(:vendor).permit(:company, :contact_name, :phone, :email, :moq, :cost_per_item, :payment_method, :terms, :turnover, :returns, :notes)
end
Try changing the code in Vendor to
class Vendor < ApplicationRecord
has_many :fotos
def self.search(search)
if search
Vendor.where('lower(name) LIKE ?', "'%#{search.downcase}%'")
else
Vendor.all
end
end
end
My search bar isn't showing up
You should change the following
<% form_tag vendors_path, :method => 'get' do %>
to
<%= form_tag vendors_path, :method => 'get' do %>
# Notice that <%= %> evaluates and prints the output
Originally I had :committed days working beautifully, but upon changing up the models a bit in order to accommodate the User's ability to check off if he missed a :committed day I now get an error message for the code relating to :committed:
undefined method to_date for nil:NilClass
Line #30 n_days = ((date_started.to_date)..Date.today).count { |date| committed_wdays.include? date.wday }
This code comes from the habit model:
class Habit < ActiveRecord::Base
belongs_to :user
has_many :levels
has_many :days, through: :levels #for being able to access Habit.find(*).days
accepts_nested_attributes_for :levels, :days
before_save :set_level
acts_as_taggable
serialize :committed, Array
def evaluate(user)
levels.each { |level| level.evaluate }
user.missed_levels << levels.where(passed: false).ids
user.missed_days << days.where(missed: true).ids
user.save
end
def self.committed_for_today
today_name = Date::DAYNAMES[Date.today.wday].downcase
ids = all.select { |h| h.committed.include? today_name }.map(&:id)
where(id: ids)
end
def levels
committed_wdays = committed.map { |day| Date::DAYNAMES.index(day.titleize) }
n_days = ((date_started.to_date)..Date.today).count { |date| committed_wdays.include? date.wday }
case n_days
when 0..9
1
when 10..24
2
when 25..44
3
when 45..69
4
when 70..99
5
else
"Mastery"
end
end
private
def set_level
self.level = levels
end
end
The logic behind it all is that a User creates a habit he wants to challenge. To achieve "mastery" in the habit he must complete 5 levels. Each level has a certain amount of :committed days that must be completed before advancing, as broken down above with n_days.
The User commits in the _form to what days (Sun thru Sat) he wants to do the habit. For example he could just choose sun, wed, sat. Then the app should only calculate n_days according to non-:missed :committed days (once 10 of those days passes it moves onto the 2nd level).
class Level < ActiveRecord::Base
belongs_to :habit
belongs_to :user
has_many :days
accepts_nested_attributes_for :days
def evaluate
if days.where(missed: true ).count == days_needed
update_attributes(passed: false)
else
update_attributes(passed: true)
end
end
end
class Day < ActiveRecord::Base
belongs_to :level
belongs_to :habit
end
class HabitsController < ApplicationController
before_action :set_habit, only: [:show, :edit, :update, :destroy]
before_action :logged_in_user, only: [:create, :destroy]
def index
if params[:tag]
#habits = Habit.tagged_with(params[:tag])
else
#habits = Habit.all.order("date_started DESC")
#habits = current_user.habits
end
end
def show
end
def new
#goal = current_user.goals.build
#habit = current_user.habits.build
#level = current_user.levels.build
3.times { #level.days.build }
end
def edit
end
def create
#habit = current_user.habits.build(habit_params)
#levels = #habit.levels
if #habit.evaluate(#user)
redirect_to #habit, notice: 'Habit was successfully created.'
else
#feed_items = []
render 'pages/home'
end
end
def update
if #habit.update(habit_params)
redirect_to #habit, notice: 'Habit was successfully updated.'
else
render action: 'edit'
end
end
def destroy
#habit.destroy
redirect_to habits_url
end
private
def set_habit
#habit = Habit.find(params[:id])
end
def correct_user
#habit = current_user.habits.find_by(id: params[:id])
redirect_to habits_path, notice: "Not authorized to edit this habit" if #habit.nil?
end
def habit_params
params.require(:habit).permit(
:user_id,
:level,
:left,
:date_started,
:trigger,
:target,
:positive,
:negative,
:tag_list,
:committed => [],
:levels_attributes => [
:passed,
:days_attributes => [
:missed,:level_id]])
end
end
<%= simple_form_for(#habit) do |f| %>
<%= f.error_notification %>
<div class="america">
<form>
<div class="committed">
<%= f.label "Committed to:" %>
<%= f.collection_check_boxes :committed, Date::DAYNAMES, :downcase, :to_s %>
</div>
<p>
<div class="date-group">
<label> Started: </label>
<%= f.date_select :date_started, :order => [:month, :day, :year], class: 'date-select' %>
</div>
</p>
<p>
<%= f.text_field :trigger, class: 'form-control', placeholder: 'Enter Trigger' %></p>
<p>
<%= f.text_field :tag_list, habit: #habit.tag_list.to_s.titleize, class: 'form-control', placeholder: 'Enter Action' %>
</p>
<p>
<%= f.text_field :target, class: 'form-control', placeholder: 'Enter Target' %>
</p>
<p>
<%= f.text_field :positive, class: 'form-control', placeholder: 'Enter Reward' %>
</p>
<% 5.times.each_with_index do |number, index| %>
<h1>Level <%= index + 1 %></h1>
<%= f.fields_for :levels do |level| %>
<%= level.fields_for :days do |day| %>
<%= day.label :missed %>
<%= day.check_box :missed %> <br/>
<% end %>
<% end %>
<% end %>
<div class="america2">
<%= button_tag(type: 'submit', class: "btn") do %>
<span class="glyphicon glyphicon-plus"></span>
<% end %>
<%= link_to habits_path, class: 'btn' do %>
<span class="glyphicon glyphicon-chevron-left"></span>
<% end %>
<%= link_to #habit, method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn' do %>
<span class="glyphicon glyphicon-trash"></span>
<% end %>
</div>
</form>
</div>
<% end %>
<!-- Default bootstrap panel contents -->
<div id="valuations" class="panel panel-default">
<div class="panel-heading"><h4><b>HABITS</b></h4></div>
<!-- Table -->
<table>
<thead>
<tr>
<th>Level</th>
<th>Left</th>
<th>Strike</th>
<th>Trigger</th>
<th>Action</th>
<th>Target</th>
<th>Reward</th>
<th>Days</th>
</tr>
</thead>
<tbody>
<% #habits.each do |challenged| %>
<tr>
<td><%= challenged.level %></td>
<td><%= challenged.left %></td>
<td>
<%= link_to edit_habit_path(challenged) do %>
<%= [params[:missed]].flatten.length %>
<% end %></td>
<td><%= challenged.trigger %></td>
<td class="category">
<b><%= raw challenged.tag_list.map { |t| link_to t.titleize, taghabits_path(t) }.join(', ') %></b>
</td>
<td><%= challenged.target %></td>
<td><%= challenged.positive %></td>
<td class= "committed">
<%= challenged.committed.map { |d| d.titleize[0,3] }.join ', ' %></td>
</tr>
<% end %>
</tbody>
</table>
</div>
Thank you so much for your help!
Some of this code came from this answer here: How to integrate :missed days with :committed days in habits.rb? which messed up what worked with this answer: How to Make :level Change Based on :committed Days?
It appears that date_started is an attribute of your Habit model, probably a database column, and that there are NULLs in date_started. Open up your Rails console and see if this is the case with:
Habit.where(date_started: nil).count
If you expect that date_started should never be null, add a validation to ensure that is the case. As soon as you test the code which is saving nulls into that column, the validation errors will point you to the bug.
On the other hand, if you want to allow nulls in date_started, then rewrite your levels method to allow for that.
I'm trying to build a small expense tracking app. Using the nested_form gem to add line items. There is an Expense model which accepts nested attributes. Items belong to expenses and there is a foreign key association. Here's the expense controller:
class ExpensesController < ApplicationController
def new
#expense = Expense.new
#item = #expense.items.build
end
def index
#expenses = Expense.all
##items = Item.where(:expense_id => #expense.id)
end
def show
#expense = Expense.find(params[:id])
#items = Item.where(:expense_id => #expense.id)
end
def create
#expense = Expense.new(expense_params)
respond_to do |format|
if #expense.save
format.html { redirect_to #expense, notice: 'Expense Report Submitted.' }
format.json { render :show, status: :created, location: #expense }
else
format.html { render :new }
format.json { render json: #expense.errors, status: :unprocessable_entity }
end
end
end
def edit
#expense = Expense.find(params[:id])
end
def update
#expense = Expense.find(params[:id])
if #expense.save(expense_params)
flash[:notice] = "Expense Report Updated"
redirect_to #expense
else
render 'edit'
end
end
def destroy
#expense = Expense.find(params[:id])
#expense.destroy
redirect_to 'root'
end
private
def expense_params
params.require(:expense).permit(:department_id, :expense_type_id, :notes, items_attributes: [:id, :description, :amount, :issue_date, :_destroy])
end
end
The form looks like:
<%= nested_form_for (#expense) do |f| %>
<% if #expense.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#expense.errors.count, "error") %> prohibited
this expense from being saved:</h2>
<ul>
<% #expense.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class"row">
<div class="col-md-8">
<div class="form-group">
<%= f.label :department_id %><br>
<%= f.collection_select(:department_id, Department.all, :id, :department_name, prompt: true, class: "dropdown-menu") %>
</div>
<div class="form-group">
<%= f.label :expense_type_id %><br>
<%= f.collection_select(:expense_type_id, ExpenseType.all, :id, :expense_name, prompt: true, class: "form-control") %>
</div>
<%= f.fields_for :items do |i| %>
<div class="form-group">
<%= i.label :description%>
<%= i.text_field :description, class: "form-control" %>
</div>
<div class="form-group">
<%= i.label :amount%>
<%= i.text_field :amount, class: "form-control" %>
</div>
<div class="form-group">
<%= i.label :issue_date%>
<%= i.date_select :issue_date, class: "form-control" %>
</div>
<%= i.link_to_remove "Remove", class: "btn btn-default" %>
<% end %>
<div><p><%= f.link_to_add "Add Expense", :items, class: "btn btn-default" %></p></div>
<div class="form-group">
<%= f.label :notes %>
<%= f.text_area :notes, class: "form-control" %>
</div>
<%= f.submit "Submit", class: "btn btn-primary" %>
<% end %>
</div>
</div>
When I hit submit, the expense and items are saved. I checked with Sqlite browser and the foreign key values are captured for each item.
The index file looks like:
<% #expenses.each do |expense| %>
<tr>
<td><%= expense.item.description %></td>
<td><%= number_to_currency(expense.item.amount) %></td>
<td><%= expense.item.issue_date %></td>
<% end %>
I tried the usual combinations (like expense.item.description) by passing through a block, but they aren't working. I would like to know how to display the expense and the associated items in the show and index pages.
Looking at your new action, in your models you would have
class Expense < ActiveRecord::Base
has_many :items
accepts_nested_attributes_for :items
end
So when you are doing expense.items in your view it gives you an active record relation(since expense has many items), try this:
<% #expenses.each do |expense| %>
<% expense.items.each do |item| %>
<tr>
<td><%= item.description %></td>
<td><%= number_to_currency(item.amount) %></td>
<td><%= item.issue_date %></td>
</tr>
<% end %>
<% end %>
Brand new to rails here. I'm trying to implement a user authentication system using a password and a hashing algorithm. Now when I try to create a new user, the password attribute of the user is always nil.
Here is my User/new view:
<% #page_title = 'New Users' %>
<div class="user new">
<h2>Create User</h2>
<%= form_for(:user, :url => {:action => 'create'}) do |f| %>
<%= render(:partial => 'form', :locals => {:f => f} ) %>
<div class="form-buttons">
<%= submit_tag('Create User') %>
</div>
<% end %>
</div>
<%= link_to 'Back', users_path %>
And my partial layout _form:
<% 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 |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<table summary="Admin user form fields">
<tr>
<th><%= f.label(:first_name) %></th>
<td><%= f.text_field(:first_name) %></td>
</tr>
<tr>
<th><%= f.label(:last_name) %></th>
<td><%= f.text_field(:last_name) %></td>
</tr>
<tr>
<th><%= f.label(:email) %></th>
<td><%= f.text_field(:email) %></td>
</tr>
<tr>
<th><%= f.label(:password) %></th>
<td><%= f.text_field(:password) %></td>
</tr>
</table>
However, by the time we get to the controller, #user.password is always nil. Why isn't the value of the :password form being brought through? Code from the controller:
def create
#user = User.new(user_params)
flash[:notice] = "Password: " + #user.password #ALWAYS NIL
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: 'User was successfully created.' }
format.json { render action: 'show', status: :created, location: #user }
else
format.html { render action: 'new' }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
Password is attr_accessor in the model. Here is the model code:
class User < ActiveRecord::Base
attr_accessor :password #not value in database, only in model
validates_length_of :password, :within => 6..25, :on => :create
before_save :create_hashed_password
after_save :clear_password
def self.hash_with_salt(password= "", salt="")
Digest::SHA1.hexdigest("Put #{salt} on the #{password}")
end
#makes a salt for encription using the user's email (unique) and time (random)
def self.make_salt(email="")
Digest::SHA1.hexdigest("Use #{email} with #{Time.now} 2 make salt")
end
#will return user if login is successful else returns fasle
def self.authenticate(email="", password="")
user = User.find_by_email(email)
if user && user.password_match?(password)
return user
else
return false
end
end
#The same password string with the same hash method should always generate
#the same hashed_password
def password_match?(password="")
hashed_password == User.hash_with_salt(password, salt)
end
private
def create_hashed_password
#Whenever :password has a value, hashing is needed
unless password.blank?
self.salt = User.make_salt(username) if salt.blank?
self.hashed_password = User.hash_with_salt(password, salt)
end
end
def clear_password
self.password = nil
end
end
Thanks in advance for your help.
In your create action change this:
#user = User.new(user_params)
to
#user = User.new(params[:user])