I want to use ajax in my application here is my problem :
I have a income voucher controller and model which receives incomes from various sources.
for this i have a payment_mode model with card, cheque and internet_banking payment option here is my code:
From model:
income_voucher
class IncomeVoucher < ActiveRecord::Base
has_one :payment_mode, :foreign_key => :voucher_id
end
** payment_mode:**
class PaymentMode < ActiveRecord::Base
belongs_to :transactionable, :polymorphic => true
belongs_to :receipt_voucher
end
card_payment:
class CardPayment < ActiveRecord::Base
has_one :payment_mode, :as => :transactionable, :dependent => :destroy
end
similar in cheque and Internet banking model .
My controller:
income_vouchers_controller:
class IncomeVouchersController < ApplicationController
def new
#income_voucher = IncomeVoucher.new
#invoices = current_company.invoices
#income_voucher.build_payment_mode
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #income_voucher }
end
end
def create
#income_voucher = IncomeVoucher.new(params[:income_voucher])
transaction_type = params[:transaction_type]
payment_mode = nil
if transaction_type == 'cheque'
payment = ChequePayment.new(params[:cheque_payment])
payment.amount = #income_voucher.amount
elsif transaction_type == 'card'
payment = CardPayment.new(params[:card_payment])
payment.amount = #income_voucher.amount
elsif transaction_type == 'ibank'
payment = InternetBankingPayment.new(params[:internet_banking_payment])
payment.amount = #income_voucher.amount
else
payment = CashPayment.new
payment.amount = #income_voucher.amount
end
payment_mode = PaymentMode.new
payment_mode.transactionable = payment
#income_voucher.payment_mode = payment_mode
respond_to do |format|
if #income_voucher.save
format.html { redirect_to(#income_voucher, :notice => 'Income voucher was successfully created.') }
format.xml { render :xml => #income_voucher, :status => :created, :location => #income_voucher }
else
format.html { render :action => "new" }
format.xml { render :xml => #income_voucher.errors, :status => :unprocessable_entity }
end
end
end
In my form i did this:
<%= render :partial => "card_payment" %>
<%= render :partial => "cheque_payment" %>
<%= render :partial => "internet_banking_payment" %>
friend till now i am rendering my partials simply as we do in rails but now i want to do this using ajax. I hope you guy's have done this earlier.
thanks
It's simple:
In your javascript (on page, for example:
$.ajax({
url: "your_path",
data: { //params if needed
your_param_name: param,
your_param_name2: param2
}
});
In your routes:
match 'your_path' => 'y_controller#y_method'
In y_controller:
def y_method
# do smth with params[:your_param_name] if needed
respond_to do |format|
format.js
end
end
In your y_method.js.erb:
$('#your-div').html('<%= raw escape_javascript render("cart_payment") %>'); //instead html() may be append()
Related
I have a model called Test that accepts_nested_attributes_for SubTest. A Test basically has an id, and there are multiple SubTests associated with an individual Test.
I want to validate that an attribute of the SubTest is numeric. Here are my models so far.
class Test < ActiveRecord::Base
has_many :sub_tests
accepts_nested_attributes_for :sub_tests
end
class SubTest < ActiveRecord::Base
belongs_to :test
validates :measurement, :numericality => true, :allow_nil => true
end
Here is the Test controller
def create
respond_to do |format|
if #test.save
flash.now[:notice] = "Test Created"
format.html { redirect_to(#test) }
format.xml { render :xml => #test, :status => :created, :location => #test }
format.js
else
flash.now[:error] = "[Error] Test Not Created Because: #{#test.errors.full_messages.join(", ")}"
format.html { render :action => "new" }
format.xml { render :xml => #test.errors, :status => :unprocessable_entity }
format.js
end
end
end
I want the create action in the controller to throw an error if the user enters a non-numeric string in the form for the sub_test.
Currently, if I enter non-numeric values for a sub_test.measurement, Rails doesn't create the Test or SubTest objects (desired behavior). But for some reason no error is thrown, and the Test controller triggers the create.js.erb partial.
I'm getting the impression that the validation for the numericality of sub_test.measurement should actually happen in the Test model, but I'm not sure how to write a custom validation method that tests for numericality.
Thanks in advance!
Got it. I needed to specify an _error.js.erb partial in my Test controller.
def create
respond_to do |format|
if #test.save
flash.now[:notice] = "Test Created"
format.html { redirect_to(#test) }
format.xml { render :xml => #test, :status => :created, :location => #test }
format.js
else
flash.now[:error] = "[Error] Test Not Created Because: #{#test.errors.full_messages.join(", ")}"
format.html { render :action => "new" }
format.xml { render :xml => #test.errors, :status => :unprocessable_entity }
format.js { render :partial => 'error' }
end
end
In the error partial I just appended my #messages div (since I'm doing form submissions through ajax.)
upload controller
def create
#upload = #order.uploads.build(params[:uploadtwo])
respond_to do |format|
if #upload.save
format.html { redirect_to root_path, :notice => 'File was successfully uploaded.' }
format.json { render :json => #upload, :status => :created, :location => #upload }
else
format.html { render :action => "new" }
format.json { render :json => #upload.errors, :status => :unprocessable_entity }
end
end
upload model
belongs_to :order
order model
has_many :uploads
i get error [NoMethodError in UploadtwosController#create ], [undefined method `uploads' for nil:NilClass]
anybody knows what am not doing?
Just declaring belongs_to :order in your Upload model does not mean that #order will automatically be defined in the controller. Perhaps what you want is a before_filter in the controller which will set #order?
I am creating a very basic rails app for the first time with 2 resources, Departments(depts) and Members. I believe I have used nested resources correctly, but for some reason after running rails server, the :id for the parent resource is not being generated/passed correctly. Root is the depts#index and from here I can do new and edit using _form.haml rendered in the new and edit views. However, when I do /depts/3 I get error with "can't find dept with id=3". Clicking through to edit from index gives me /depts/63/edit in the URL - I'm not sure where this id=63 has come from. Trying to get to 'show' action by typing /dept/63 in the URL does not work. I created Depts on it's own at first, got it working with all actions and views, something has gone wrong since I added Members resource.
routes.rb
resources :depts do
resources :members
end
depts_controller.rb
def index
#depts = Dept.all
respond_to do |format|
format.html
format.json { render :json => #depts }
end
end
def show
#dept = Dept.find(params[:dept_id])
respond_to do |format|
format.html
format.json { render :json => #dept }
end
end
def new
#dept = Dept.new(params[:dept])
respond_to do |format|
format.html
format.json { render :json => #dept }
end
end
def create
#dept = Dept.new(params[:dept])
respond_to do |format|
if #dept.save
format.html { redirect_to :action => 'index' }
format.json { render :json => #dept }
else
format.html { render :action => 'new' }
format.json { render :json => #dept }
end
end
end
def edit
#dept = Dept.find(params[:id])
end
def update
#dept = Dept.find(params[:id])
respond_to do |format|
if #dept.update_attributes(params[:dept])
format.html { redirect_to :action => 'index'}#, :id => #dept }
format.json { render :json => #dept }
else
format.html { redirect_to :action => 'edit' }
format.json { render :json => #dept }
end
end
end
def destroy
#dept = Dept.find(params[:id])
#dept.destroy
respond_to do |format|
format.html { redirect_to :action => 'index' }
format.json { render :json => #dept }
end
end
end
show.haml
%p= #dept.name
%p= link_to "back", {:action => 'index'}
index.haml
%h1 DEPARTMENTS
%ol
- #depts.each do |d|
%li= link_to d.name
%p= link_to 'edit department', edit_dept_path(d)
%p= link_to 'get rid of department!', d, :method => :delete, :id => d.id
%br
%p= link_to "ADD A NEW DEPARTMENT", new_dept_path
in show method change:
#dept = Dept.find(params[:dept_id])
to:
#dept = Dept.find(params[:id])
and in new method change:
#dept = Dept.new(params[:dept])
to just:
#dept = Dept.new
Hi i know it's silly but true i got this when i edit any entry.
I have an expense model and an expense_line_item and a paid_line_item model, it is created properly when i create a new entry but on editing previous entry it adds a new entry instead of updating, i. e. at update action it fires insert query. here is my code:
My controller:
def new
#menu = 'Expenses'
#page_name = 'Record New Expenses'
#expense = Expense.new
#expense.expense_line_items.build
#expense.paid_line_items.build
#expense.voucher_number = "EXP"+Time.now.to_i.to_s
#from_accounts = TransactionType.fetch_from_accounts(current_company.id, 'payments')
#to_accounts = TransactionType.fetch_to_accounts(current_company.id, 'payments')
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #expense }
end
end
# GET /expenses/1/edit
def edit
#menu = 'Expenses'
#page_name = 'Edit Expenses Entry'
#expense = Expense.find(params[:id])
#from_accounts = TransactionType.fetch_from_accounts(current_company.id, 'payments')
#to_accounts = TransactionType.fetch_to_accounts(current_company.id, 'payments')
end
# POST /expenses
# POST /expenses.xml
def create
#expense = Expense.new(params[:expense])
#expense.created_by = current_user.id
#expense.company_id = current_company.id
respond_to do |format|
if #expense.save
format.html { redirect_to(#expense, :notice => 'Expense was successfully created.') }
format.xml { render :xml => #expense, :status => :created, :location => #expense }
else
#menu = 'Expenses'
#page_name = 'Record New Expenses'
#from_accounts = TransactionType.fetch_from_accounts(current_company.id, 'payments')
#to_accounts = TransactionType.fetch_to_accounts(current_company.id, 'payments')
format.html { render :action => "new" }
format.xml { render :xml => #expense.errors, :status => :unprocessable_entity }
end
end
end
# PUT /expenses/1
# PUT /expenses/1.xml
def update
#expense = Expense.find(params[:id])
respond_to do |format|
if #expense.update_attributes(params[:expense])
format.html { redirect_to(#expense, :notice => 'Expense was successfully updated.') }
format.xml { head :ok }
else
#menu = 'Expenses'
#page_name = 'Edit Expenses Entry'
format.html { render :action => "edit" }
format.xml { render :xml => #expense.errors, :status => :unprocessable_entity }
end
end
end
My Model:
expense model:
class Expense < ActiveRecord::Base
has_many :expense_line_items
has_many :paid_line_items
accepts_nested_attributes_for :expense_line_items, :reject_if => lambda {|a| a[:account_id].blank? } , :allow_destroy => true
accepts_nested_attributes_for :paid_line_items, :reject_if => lambda {|a| a[:account_id].blank? }, :allow_destroy => true
#validations
validates_presence_of :expense_date, :voucher_number
validates_presence_of :expense_line_items
validates_associated :expense_line_items
validates_presence_of :paid_line_items
validates_associated :paid_line_items
end
expense_line_item:
class ExpenseLineItem < ActiveRecord::Base
belongs_to :expense
end
paid_line_item:
class PaidLineItem < ActiveRecord::Base
belongs_to :expense
end
My form :
<%= form_for(#expense) do |f| %>
<% #expense.expense_line_items.each_with_index do |expense_line_item, index| %>
<%= render "expense_line_items", :expense_line_item => expense_line_item, :index => index %>
<% end %>
<tr id="row_link" valign="top">
<td valign="top" colspan="6">
<%= link_to "Add new row",{:action => :add_row, :index => #expense.expense_line_items.size}, :remote => true %>
</td>
</tr>
<% #expense.paid_line_items.each_with_index do |paid_line_item, index| %>
<%= render "paid_line_items", :paid_line_item => paid_line_item, :index => index %>
<% end %>
<tr id="to_row_link" valign="top">
<td valign="top" colspan="6">
<%= link_to "Add new row",{:action => :add_to_row, :index => #expense.paid_line_items.size}, :remote => true %>
</td>
</tr>
<% end %>
i got frustrated, thanks in advance .
i have found a solution for this problem. When i tried to update a lineitem it take it as a new one hence i have to pass a hidden lineitem_id for update action. i have used
below code :
<%= hidden_field_tag "expense[expense_line_items_attributes][#{index}][id]",expense_line_item.id%>
and it works for me.
I was following the tutorial at http://www.logansbailey.com/ and modified it to enable an unregistered person to be able to register with a username, email and password.
I already enabled a logged in user to modify his/her email and password but not the username.
What I want to add is:
1) to enable a logged in user to be able to see/reach his/her username and email,
2) to enable a user with admin_flag set (I handled this in the sql table and created the user) to be able to see/modify all user records.
I modifyed the app/cotrollers/user_controller.rb like this:
class UsersController < ApplicationController
before_filter :is_user, :only => [:index, :show, :edit, :update, :destroy]
def index
#users = User.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #users }
end
end
def show
#user = User.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #user }
end
end
def new
#user = User.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #user }
end
end
def edit
end
def create
#user = User.new(params[:user])
respond_to do |format|
if #user.save
flash[:notice] = 'Registration successful.'
format.html { redirect_to(:controller => 'home', :action => 'tutorial') }
format.xml { render :xml => #user, :status => :created, :location => #user }
else
format.html { render :action => "new" }
format.xml { render :xml => #user.errors, :status => :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #user.update_attributes(params[:user])
flash[:notice] = 'Your profile was successfully updated.'
format.html { redirect_to(:controller => 'home', :action => 'index') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #user.errors, :status => :unprocessable_entity }
end
end
end
def destroy
#user = User.find(params[:id])
#user.destroy
respond_to do |format|
format.html { redirect_to(users_url) }
format.xml { head :ok }
end
end
def is_user
if User.exists?(params[:id])
#user = User.find(params[:id]);
if current_user.admin_flag == true
flash[:notice] = 'Welcome Admin'
end
if !current_user || current_user.id != #user.id
flash[:notice] = 'You do not have access to that page'
redirect_to(:controller => 'home', :action => 'index')
end
else
flash[:notice] = 'You do not have access to that page'
redirect_to(:controller => 'home', :action => 'index')
end
end
end
The file app/models/user.rb is:
class User < ActiveRecord::Base
acts_as_authentic
end
And I can confirm that the admin_flag set user is get correctly since the file app/views/layouts/application.html.erb containing:
<div id="admin">
<% if current_user %>
<% if current_user.admin_flag == true %> |
<%= link_to "Users", users_path %>
<% end %>
<% end %>
</div>
correctly displays the 'Users' link when I log in as the admin.
Now the problem is that I can't get the show all users, edit other users etc.. functionality. As the admin, I can show and modify the admin user just like all the other ordinary users, meaning I can't modify the username, too.
What may be wrong here?
When you added a boolean attribute admin to user in the right way, the Rails should add question-mark method admin? in User model. It's not important but for convenience.
On every method you want to protect from unwanted actions use before_filter:
class UsersController < ApplicationController
before_filter :admin_user, :only => :destroy
before_filter :correct_user, :only => [:edit, :update]
def destroy
end
...
private
def admin_user
redirect_to(root_path) unless current_user.admin?
end
def correct_user
#user = User.find(params[:id])
redirect_to(root_path) unless current_user?(#user) || current_user.admin?
end
end
In views more convenient to use current_user.admin?
<div id="admin">
<% if current_user.admin? %>
<%= link_to "Users", users_path %>
<% end %>
</div>