I put them in context, I am from Chile, and I am building a reservation engine and in the engine I need to define the current account of the clients, for that I made a list and placed it in a select and it gives me the following
error undefined method `current_acounts_path' for #ActionView::Base:0x00000000024478
Did you mean? current_accounts_path
How do I solve the problem Thanks
I share the codes thanks
Controller
class CurrentAccountsController < ApplicationController
before_action :authenticate_user!
def index
#currentaccounts = CurrentAcount.all
end
def new
#currentaccount = CurrentAcount.new
#clients = Client.all
end
def create
#currentacount = CurrentAcount.new(set_params)
#currentacount.client_id = #client.id
if (#currentacount.save)
redirect_to current_accounts_path, notice: "Cuenta Corriente Guardada"
else
render :new
flash.alert = "No se pudo Guardar Cuenta Corriente"
end
end
def edit
end
def update
#currentaccount.client_id = #client.id
if (#currentaccount.update(set_params))
redirect_to current_accounts_path, notice: "Modificacion de Cuenta Corriente Guardada"
else
render :edit
flash.alert = "No se pudo Modificar la Cuenta Corriente"
end
end
def show
end
def destroy
if (#currentaccount.destroy)
redirect_to current_accounts_path, notice: "Eliminada Cuenta Corriente"
else
redirect_to current_accounts_path, notice: "No se pudo Eliminar Cuenta Corriente"
end
end
private
def set_params
params.require(:current_acount).permit(:mail, :client_id, :number, :bank, :city, :telephone_contact, :type_account)
end
def set_client
#client = Client.find(params[:client_id])
end
end
Model
class CurrentAcount < ApplicationRecord
belongs_to :client
end
Form
<%= simple_form_for #currentaccount do |f| %>
<%= f.association :client, collection: #clients.map { |c| [c.name, c.id] } %>
<%= f.input :number, label: "Numero cuenta Corriente" %>
<%= f.input :type_account, prompt:"Elija tipo de cuenta", collection: ["Cuenta Correinte", "Cuenta Vista", "Cuenta de Ahorro"]%>
<%= f.input :bank, prompt:"Elija un Banco", collction: ["Banco de Chile", "Banco Internacional", "Scotiabank Chile ", "BCI", "Corpbanca", "Bnaco BICE", "HSBC Bank (Chile)", "Banco Santander-Chile", "Banco Itaú Chile", "Banco Security", "Banco Falabella", "Deutche Bank (Chile)", "Banco Ripley", "Rabobank Chile", "Banco Consorcio", "Banco Penta", "Banco Paris", "Banco Bilbao Vizcaya Argentaria, Chile (BBVA)", "Banco BTG Pactual Chile", "BancoEstado", "Banco Do Brasil S.A.", "JP MORGAN BANK, N.A.", "Banco de La Nacion Argentina", "The Bank of Tokyo-Mitsubishi UFJ, LTD"] %>
<%= f.input :city, label: "Ciudad"%>
<%= f.input :telephone_contact, label: "Telefono"%>
<%= f.input :email_contact, label: "Email"%>
<%= f.submit "Agregar" %>
<%= link_to "Volver", current_accounts_path(#reservation.client_id) %>
<% end %>
Thank for all
Change your model to have the correct spelling. Naming needs to be consistent:
CurrentAccount # model
resources :current_accounts # routes
models/current_account.rb # filenames and
views/current_accounts/ # directories are also important.
#current_accounts # instance variables; less important,
#current_account # but why make them different.
Run a generator to get a default set up:
$ bin/rails generate scaffold_controller CurrentAccount
Just to note a few places:
#currentaccounts = CurrentAcount.all
# ^^ ^
#currentaccount = CurrentAcount.new
# ^^ ^
#currentacount = CurrentAcount.new(set_params)
# ^ ^
The actual error is coming from the form builder, because it is using CurrentAcount model to generate a URL for the form action:
<%= simple_form_for #currentaccount do |f| %>
# which is trying to get the url
<%= url_for #currentaccount %>
# which is trying to call a named route based on the class name
# something like this:
<%= send "#{#currentaccount.model_name.route_key}_path" %>
# => undefined method `current_acounts_path'
Related
My forms work fine but I keep getting undefined method empty? for nil:NilClass on my select tags whenever I add form validations. I found that the fact that I'm putting controller variables into the select function on the form is causing the problem.
I have a long array of options for the select tags so even though I know it would work if I just paste the arrays in the select function I want to find a way to keep it as clean as I have it now
Here's my controller
class MembersController < ApplicationController
before_action :find_member, only: [:edit, :update, :delete, :destroy]
before_action :form_vars, only: [:new, :edit, :executives]
def find_member
#members = Member.find(params[:id])
end
...
def new
#members = Member.new
end
def create
#members = Member.new(members_params) #the new Members entry is recreated through the strong params method
#members.is_executive = true #Remove for members feature
if #members.save #if the entry saves
redirect_to({ action: 'executives' }, notice: #members.first_name + ' ' + #members.last_name + ' has been created!') #show all of the present entries
else
render({ action: 'new' }) #redisplay the create an entry page
end
end
end
Here is my form
<div class="forms">
<%= form_for(#members) do |member| %>
<small>* = Required</small>
<label>First Name*</label><br>
<%= member.text_field :first_name %><br>
<label>Last Name*</label><br>
<%= member.text_field :last_name %><br>
<label>LinkedIn Profile Address</label><br>
<%= member.url_field :linkedinurl %><br>
<label>Photo*</label><br>
<%= member.file_field :avatar %><br>
<%= member.label 'Major*' %><br>
<%= member.select(:major, #major, selected: #members.major, prompt: 'Select Major') %><br>
<label>E-Mail*</label><br>
<%= member.text_field :email %><br>
<label>Graduation Date</label><br>
<%= member.select(:graduation_date, [1], selected: #members.graduation_date, prompt: 'Month') %>
<%= member.select(:graduation_date, Date.today.year..Date.today.year+5, prompt: 'Year') %><br>
<!-- <%= member.label(:is_executive, "Is this member an executive?") %>
<%= member.check_box(:is_executive) %></br> -->
<label>Executive Position*</label><br>
<%= member.select(:executive_position, #executive, selected: #members.executive_position, prompt: 'Select Position') %><br>
<%= member.submit %>
<b><%= link_to "Cancel", '/members/executives'%></b>
<% end %>
</div>
My select tag options are declared in the application controller since I'm using the same select tag in multiple forms on other models
class ApplicationController < ActionController::Base
...
def form_vars
#majors = ['Accounting', 'Africana Studies', 'Anthropology', 'Architecture', 'Art', 'Art History', 'Athletic Training', 'Biology', 'Business Administration', 'Chemistry', 'Child and Family Development', 'Civil Engineering', 'Civil Engineering Technology', 'Computer Science', 'Computer Engineering', 'Construction Management', 'Criminal Justice', 'Dance', 'Earth and Environmental Sciences', 'Economics', 'Electrical Engineering', 'Electrical Engineering Technology', 'Elementary Education', 'English', 'Environmental Studies', 'Exercise Science', 'Finance', 'Fire Safety Engineering Technology', 'French', 'Geography', 'Geology', 'German', 'History', 'International Business', 'International Studies', 'Japanese', 'Latin American Studies', 'Management', 'Management Information Systems', 'Marketing', 'Mathematics', 'Mathematics for Business', 'Mechanical Engineering', 'Mechanical Engineering Technology', 'Meteorology', 'Middle Grades Education', 'Music', 'Neurodiagnostics and Sleep Science', 'Nursing', 'Ops & Supply Chain Management', 'Pre-Law', 'Philosophy', 'Physics', 'Political Science', 'Psychology', 'Public Health', 'Religious Studies', 'Respiratory Therapy', 'Social Work', 'Sociology', 'Spanish', 'Special Education', 'Systems Engineering', 'Theatre']
#executive = ['President', 'Vice President', 'Treasurer', 'Secretary', 'Strategic Advisor', 'Director of Strategic Partnerships', 'Director of Programs', 'Director of Public Relations', 'Director of Publications', 'Director of Community Service', 'Director of Fundraising', 'Historian', 'Digital Administrator']
#grad_month = ['May', 'December']
end
end
What's the best way to do this so that I can keep the array out of my form file but have working validations? I'm new to Rails so any other best practice tips are welcome Thanks!
Valiadtions are the part of ActiveRecord. So, for validations work you may add all needed values into the model as follows:
class Member < ActiveRecord::Base
MAJORS = ['Accounting', 'Africana Studies', 'Anthropology', 'Architecture', 'Art', ...]
EXECUTIVES = ['President', 'Vice President', 'Treasurer', 'Secretary', ...]
GRAD_MONTH = ['May', 'December']
validates :major, inclusion: { in: MAJORS, allow_blank: false }
validates :executive_position, inclusion: { in: EXECUTIVES, allow_blank: false }
validates :graduation_date, inclusion: { in: GRAD_MONTH, allow_blank: false }
end
Then in your form:
<%= f.select(:executive_position, Member::EXECUTIVES, selected: #members.executive_position, prompt: 'Select Position') %>
# ...
<%= member.select(:graduation_date, Members::GRAD_MONTH, selected: #members.graduation_date, prompt: 'Month') %>
# ...
<%= member.select(:major, Member::MAJORS, selected: #members.major, prompt: 'Select Major') %><br>
Here is the documentation about inclusion validation.
With that approcah you don't need to define values in ApplicationController.
Hope that will help.
I know this kind of question is already answered multiple times but i seriously unable to figure it out what is causing a problem here, I am having trouble solving this problem. I keep getting the same error when i'm trying to create new registration ( http://localhost:3000/registrations/new?course_id=1 ) :
NoMethodError at /registrations
undefined method `id' for nil:NilClass
Here is my RegistrationsController:
class RegistrationsController < ApplicationController
before_action :set_registration, only: [:show, :edit, :update, :destroy]
def index
#registrations = Registration.all
end
def show
end
def new
#registration = Registration.new
#course = Course.new
#course = Course.find_by id: params["course_id"]
end
def create
#registration = Registration.new registration_params.merge(email: stripe_params["stripeEmail"], card_token: stripe_params["stripeToken"])
raise "Please Check Registration Errors" unless #registration.valid?
#registration.process_payment
#registration.save
redirect_to #registration, notice: 'Registration was successfully created.'
rescue Exception => e
flash[:error] = e.message
render :new
end
protect_from_forgery except: :webhook
def webhook
event = Stripe::Event.retrieve(params["id"])
case event.type
when "invoice.payment_succeeded" #renew subscription
Registration.find_by_customer_id(event.data.object.customer).renew
end
render status: :ok, json: "success"
end
private
def stripe_params
params.permit :stripeEmail, :stripeToken
end
def set_registration
#registration = Registration.find(params[:id])
end
def registration_params
params.require(:registration).permit(:course_id, :full_name, :company, :telephone, :email, :card_token)
end
end
My Registration Model:
class Registration < ActiveRecord::Base
belongs_to :course
def process_payment
customer_data = {email: email, card: card_token}.merge((course.plan.blank?)? {}: {plan: course.plan})
customer = Stripe::Customer.create customer_data
Stripe::Charge.create customer: customer.id,
amount: course.price * 100,
description: course.name,
currency: 'usd'
#Annotate Customer Id when Registration is Created
cusotmer_id = customer.id
end
def renew
update_attibute :end_date, Date.today + 1.month
end
end
Registration New.html.haml File :
%section#course-content
%section#ruby
%section.detailed-syllabus
.wrapper-inside
= form_for #registration, html: { class: "basic-grey" } do |f|
- if #registration.errors.any?
#error_explanation
%h2
= pluralize(#registration.errors.count, "error")
prohibited this registration from being saved:
%ul
- #registration.errors.full_messages.each do |message|
%li= message
.field
= f.hidden_field :course_id, value: #course.id
.field
= f.label :full_name
= f.text_field :full_name
.field
= f.label :company
= f.text_field :company
.field
= f.label :email
= f.text_field :email
.field
= f.label :telephone
= f.text_field :telephone
//‘Stripe.js’ will recognize the card data because we have marked the inputs with ‘data-stripe’ attribute as: number, cvv, exp-month and exp-year.
= javascript_include_tag "https://js.stripe.com/v2/"
:javascript
Stripe.setPublishableKey('#{Rails.application.secrets.stripe_publishable_key}');
= label_tag "Card Number", nil, required: true
.control-group
.controls
= text_field_tag :card_number, nil, class: "input-block-level", "data-stripe" => "number"
= label_tag "Card Verification", nil, required: true
.control-group
.controls
= text_field_tag :card_verification, nil, class: "input-block-level", "data-stripe" => "cvv"
= label_tag "Card Expires", nil, required: true
= select_tag :exp_month, options_for_select(Date::MONTHNAMES.compact.each_with_index.map { |name,i| ["#{i+1} - #{name}", i+1] }), include_blank: false, "data-stripe" => "exp-month", class: "span2"
= select_tag :exp_year, options_for_select((Date.today.year..(Date.today.year+10)).to_a), include_blank: false, "data-stripe" => "exp-year", class: "span1"
.actions
= f.submit "Registration Payment", class: "btn", style: "color: white;background: rgb(242, 118, 73);"
Does anyone know how to assist me in this? Greatly appreciate all the help.
Additional Can anyone please guide me through how to pass id between 2 models like this guy did between 2 models as he's creating a scaffold for one model but passing ID lets him create values for another model too without creating actions for another controller https://github.com/gotealeaf/stripe-basics.git
Edited:
GitHub Repository For This Code
https://github.com/ChiragArya/Stripe_CheckOut_Demo
From your comments, it appears the error is caused by :
#course.id being nil
The way to fix this is to ensure #course is defined properly. You need to do the following:
def new
#registration = Registration.new
#course = Course.find_by id: params["course_id"]
end
The other issue you have here is that your routes should be able to handle courses without having to append them with ?course_id=1:
#config/routes.rb
resources :registrations do
get :course_id, to: "registrations#new" #-> yoururl.com/registrations/:course_id
end
This will still give you the course_id param in the new action; just makes it more Rails.
--
Controller
You also need some structure in your code (you're aiming for fat model, thin controller). It looks like you're coming to Rails as a Ruby dev; you need to appreciate that Rails handles most of the exceptions etc for you.
Specifically, you need to look at how to remove code out of your actions:
def create
#registration = Registration.new registration_params
#registration.process_payment
if #registration.save
redirect_to #registration, notice: 'Registration was successfully created.'
else
# handle error here
end
end
private
def registration_params
params.require(:registration).permit(:course_id, :full_name, :company, :telephone, :email, :card_token).merge(email: stripe_params["stripeEmail"], card_token: stripe_params["stripeToken"])
end
-
`id' for nil:NilClass
Finally, you have to remember this error basically means the variable you're trying to invoke an action for is nil.
Ruby populates nil variables with a NilClass object, thus it's difficult to determine what the error actually is. All it means is that the variable you're trying to call a method on doesn't have the aforementioned method, as Ruby has populated it with the NilClass object.
Try changing Registration#new action to
def new
#course = Course.find(params[:course_id])
#registration = #course.registrations.new
end
add this in your def create
def create
#course = Course.find_by id: params["registration"]["course_id"]
#registration = Registration.new registration_params.merge(email: stripe_params["stripeEmail"], card_token: stripe_params["stripeToken"])
raise "Please Check Registration Errors" unless #registration.valid?
#registration.process_payment
#registration.save
redirect_to #registration, notice: 'Registration was successfully created.'
rescue Exception => e
flash[:error] = e.message
#course = Course.find_by id: params["registration"]["course_id"]
render :new
end
I have a form_tag to which I specify a POST method but each time I submit the form it is trying to use the GET method. Here is my form :
<%= form_tag (refund_path(subscription), :method => "post") do %>
<%= hidden_field_tag :subscription_id_refund, subscription.id %>
<%= submit_tag "Rembourser ce joueur", id: "export", class: "btn btn-warning"%>
<% end -%>
here is my route :
post 'refunds/:subscription_id', to: "subscriptions#refund", as: "refund"
here is my method :
def refund
#subscription = Subscription.find(params[:subscription_id_refund])
if mangopay_refund
#subscription.status == "refused"
redirect_to
flash[:notice] = "Vous avez bien procéder au remboursemend de #{#subscription.user.full_name}. Celui-ci ne participe plus au tournoi"
else
redirect_to
flash[:warning] = "Le remboursement n'a pas pu etre effectué. Merci de réessayer plus tard"
end
end
Do you know how to fix that ?
The method for the form defaults to POST.So remove :method => "post" options and try.
<%= form_tag(refund_path(subscription)) do %>
Reference : form_tag
Hi I'm trying to create an event depending on the eventable type. the eventable type is either group or shop.
Writing my code, I'm currently sure that their is a better way create my routes and controller (still a rails newbie)
Is there a way to create only one new and create method pass in the eventable type ?
Models:
class Event < ActiveRecord::Base
belongs_to :eventable, polymorphic: true
class Group < ActiveRecord::Base
has_many :events, as: :eventable
class Shop < ActiveRecord::Base
has_many :events, as: :eventable
Routes:
resources :events do
collection do
get :new_national_event
get :new_local_event
post :create_national_event
post :create_local_event
end
do
event-controller:
def index
#search = Search.new(params[:search])
#shop = find_user_shop(#search.shop_id)
#group = #shop.group
#shop_events = #shop.events
#group_events = #group.events
end
def new_national_event
#user = current_user
#event = #user.group.events.new
end
def new_local_event
#shop = find_user_shop(#search.shop_id)
#event = #shop.events.new
end
def create_national_event
user = current_user
#event = user.group.events
if #event.save!
flash.now[:notice] = "Votre événement national a bien été enregistré"
render :index
else
flash.now[:error] = "Erreur lors de l'enregistrement du événement national"
render :new
end
end
def create_local_event
user = current_user
#event = user.group.shop.events
if #event.save!
flash.now[:notice] = "Votre événement local a bien été enregistré"
render :index
else
flash.now[:error] = "Erreur lors de l'enregistrement du événement local"
render :new
end
end
views:
index.html.slim
= link_to new_national_event_events_path
= link_to new_local_event_events_path
new_national_event_events_path.html.slim
= form_for #event, :url => create_national_event_events_path, :method => :post do |f|
div class="field"
= f.text_field :title, :required => true
div class="field"
= f.text_field :threshold, :required => true
div class="form-actions"
=f.submit "Create", class: "btn blue"
If it is just the routing you are concerned with, and not the number of actions, you can use constraints to allow a single path variable send the request to one of a multiple number of actions, this can be useful in some cases where you may want to have multiple buttons to multiple actions all reading from a single form, or if you just want to simplify your routes variable naming.
use the commit_param_routing gem and in your routes file you can write something like:
resources :events do
collection do
post :save, constraints: CommitParamRouting.new(EventController::CREATENATIONAL), action: :create_national_event
post :save, constraints: CommitParamRouting.new(EventController::CREATELOCAL), action: :create_local_event
end
end
add the constants to your controller:
class EventController
CREATENATIONAL = "create national"
CREATELOCAL = "create local"
.....
end
and then all that is left is to add them to your view file submit buttons:
div class="form-actions"
.row
.col-xs-2
=f.submit EventController::CREATENATIONAL
.col-xs-2
=f.submit EventController::CREATELOCAL
sorry for if its not quite what you were looking for or unclear, my first answer!
I've build quite complex form which creates one prescription with many realtions. I am using this syntax in view:
- provide(:title, 'Create prescription')
%h1 Add medicines to prescription
.row
.span6.offset3
= form_for #prescription do |f|
= render 'shared/error_prescription_messages'
%p
= f.hidden_field :patient_id, :value => params[:patient_id]
= f.hidden_field :user_id, :value => current_user.id
= f.fields_for :relations do |builder|
= render 'child_form', :f => builder
%p= f.submit "Submit"
chlid_form is quite simple :
- it=f.options[:child_index].to_i
- n= it.to_s
%h2
= "Medicine ##{it+1}"
= f.hidden_field :medicine_id, :id => "my_medicine_id#{it}"
- if params[:prescription].nil? || params[:prescription][:relations_attributes][n.to_sym][:medicine_name].nil?
= f.autocomplete_field :medicine_name, autocomplete_medicine_name_relations_path, :id_element => "#my_medicine_id#{it}"
- else
= f.autocomplete_field :medicine_name, autocomplete_medicine_name_relations_path, :id_element => "#my_medicine_id#{it}", :value => params[:prescription][:relations_attributes][n.to_sym][:medicine_name]
= f.label :amount, "Amount of medicine boxes"
= f.number_field :amount, :value => 1
= f.label :daily
= f.number_field :daily, :value => 1
= f.label :period_in_days, "Duration of treatment (in days)"
= f.number_field :period_in_days, :value => 1
So as you can see I'm using f.options[:child_index] to get index of child (0,1,2...) cause I generate multiple items with this particular form. I then put it to variable it and sucessfully use it in :id_element => "#my_medicine_id#{it}" which works PERFECTLY fine (creates my_medicine_id0, my_medicine_id1 ....) Although it doesn't work in this line:
:value => params[:prescription][:relations_attributes][n.to_sym][:medicine_name]
where n is just n=it.to_s.
I though somethings wrong in controller but if I change this line to whatever
:value => params[:prescription][:relations_attributes]**[:'0']**[:medicine_name] or any other integer from 0 to 4 everything works great, but I NEED dynamic change in this one. So I got proof that it DOES work because it generates integer fine here "#my_medicine_id#{it}" but won't work in hash! And when I print the whole hash from params I get this:
{"patient_id"=>"7", "user_id"=>"1", "relations_attributes"=>{"0"=>{"medicine_id"=>"13490", "medicine_name"=>"Locacid 500 mcg/g (0,05%) (1 tuba 30 g)", "amount"=>"0", "daily"=>"1", "period_in_days"=>"1"}, "1"=>{"medicine_id"=>"", "medicine_name"=>"", "amount"=>"1", "daily"=>"1", "period_in_days"=>"1"}, "2"=>{"medicine_id"=>"", "medicine_name"=>"", "amount"=>"1", "daily"=>"1", "period_in_days"=>"1"}, "3"=>{"medicine_id"=>"", "medicine_name"=>"", "amount"=>"1", "daily"=>"1", "period_in_days"=>"1"}, "4"=>{"medicine_id"=>"", "medicine_name"=>"", "amount"=>"1", "daily"=>"1", "period_in_days"=>"1"}}}
so to get the values I need it's pretty obvious that
params[:prescription][:relations_attributes][SOME_KIND_OF_INETEGER][:medicine_name] should work, but doesn't.
Controller code:
class PrescriptionsController < ApplicationController
before_action :signed_in_user
before_action :doctor_user, only: [:new, :create]
before_action :pharmacist_user, only: [:update]
def new
#prescription =Prescription.new
5.times { #prescription.relations.build }
end
def create
#prescription = Prescription.new(new_prescription_params)
if #prescription.save
flash[:success] = "Prescription created."
redirect_to #prescription
else
5.times { #prescription.relations.build }
render 'new', :prescription => params[:prescription]
end
end
def show
#prescription = Prescription.find(params[:id])
#medicines = #prescription.medicines.paginate(page: params[:page], :per_page => 10)
end
def update
#prescription = Prescription.find(params[:id])
#patient = Patient.find(params[:patient_id])
if !prescription_expired?(#prescription)
#prescription.realized = 1
if #prescription.save
flash[:success] = "Prescription realized."
redirect_to #patient
else
redirect_to root_url
end
else
flash[:notice] = "Can't realize, prescription expired."
redirect_to #patient
end
end
private
def new_prescription_params
params.require(:prescription).
permit(:patient_id, :user_id, relations_attributes: [:medicine_id, :medicine_name, :amount, :daily, :period_in_days])
end
def doctor_user
redirect_to(root_url) unless current_user.function == "doctor"
end
def pharmacist_user
redirect_to(root_url) unless current_user.function == "pharmacist"
end
def prescription_expired?(presc)
presc.created_at < 1.month.ago
end
def signed_in_user
unless signed_in?
store_location
flash[:notice] = "Please log in."
redirect_to login_url
end
end
end
I run out of ideas so I ask you guys if anyone can help. Thanks.
There is no point in using params in your view since you already assigned those to your models. Also when you rendering your new action, those params doesn't exist as nothing has been send to the server yet. Just get rid of all the values from inputs.
Your partial should look like:
- it=f.options[:child_index].to_i
- n= it.to_s
%h2
= "Medicine ##{it+1}"
= f.hidden_field :medicine_id, :id => "my_medicine_id#{it}"
= f.autocomplete_field :medicine_name, autocomplete_medicine_name_relations_path
= f.label :amount, "Amount of medicine boxes"
= f.number_field :amount
= f.label :daily
= f.number_field :daily
= f.label :period_in_days, "Duration of treatment (in days)"
= f.number_field :period_in_days
If you want your fields to have default value, set default value inside your database.