i am programming in rails 4. I have done a nested form that addsnested attribuets by JavaScript , following
railscasts.
I have a feast. it has many dishes through courses and users through participations.
each users get feast assignments like that :
participations has many dishes through obligations.
My question is : why does it not save? the feast saves but the nested form parts do not...
basically I guess it is a problem with strong params somehow, or it should be in the controller or model. so I pasted them first . I pasted the HTML generated by the program - only the relevant part at the end so to make the question not too long somehow.
thanks
this is the code:
Class Feast < ActiveRecord::Base
mount_uploader :image, ImageUploader
has_many :participations, dependent: :destroy
has_many :users, :through => :participations
has_many :courses, dependent: :destroy
has_many :dishes, :through => :courses
accepts_nested_attributes_for :participations,
:allow_destroy => true
accepts_nested_attributes_for :courses,
:allow_destroy => true
and participations:
class Participation < ActiveRecord::Base
belongs_to :user
belongs_to :feast
has_many :obligations, dependent: :destroy
has_many :dishes, :through=> :obligations
has_many :groceries, :as => :needed
accepts_nested_attributes_for :obligations,
:allow_destroy => true
end
the program is complicated so in the end I of this question I will post the HTML created for one participant ,one dish and one assignment(=obligation) just so it is seen that the program works fine.
here are my nested forms - their values are updated and inserted by js.
course fields partial:
<%= link_to_function "remove","remove_fields_dish(this)", :class => "cl_both" %>
<%new_object = Feast.reflect_on_association(:courses).klass.new%>
<%= f.fields_for(:courses, new_object, child_index: "new_course", class: "fields") do
|fc| %>
<%=fc.hidden_field(:dish_id)%>
<%=fc.hidden_field(:_destroy,value: false)%>
<%end%>
participation fields partial:
<%= link_to_function "remove","remove_fields_dish(this)", :class => "cl_both" %>
<%new_object = Feast.reflect_on_association(:participations).klass.new%>
<%= f.fields_for(:participations, new_object , child_index: "new_course", class: "fields") do
|fc| %>
<%=fc.hidden_field(:dish_id)%>
<%=fc.hidden_field(:_destroy,value: false)%>
<%end%>
obligation fields partial:
<%new_object = Participations.reflect_on_association(:obligations).klass.new%>
<%= fp.fields_for(:obligations, new_object , child_index: "new_obli", class:
"fields") do |fpo| %>
<%= fpo.hidden_field(:dish_id) %>
<%= fpo.hidden_field(:_destroy,value: false) %>
<%end%>
my controller feasts_controller:
class FeastsController < ApplicationController
def list
#user_feast_m=Feast.joins(participations: :user).where(participations: {manager:
true}).to_a
#user_feast_p=Feast.joins(participations: :user).where(participations: {manager:
false}).to_a
end
def show
#feast=feast.find(params[:id])
#users=#feast.users
#dishes=(Dish.joins(obligations: {participation: :feast}).where(feast:
{id:#feast.id }).to_a + #feast.dishes).compact
end
def new
#feast= Feast.new
#myself = User.find(session[:user_id])
respond_to do |format|
format.html
format.js
end
end
def create
#feast = Feast.new(feast_params)
if #feast.save
flash[:notice]="the feast has been saved. all participants will get invitations and
assignments. hope they answer soon"
redirect_to(:action=>'list')
else
render('new')
end
end
def update
end
def edit
#feast=feast.find(params[:id])
#users=#feast.users.sort{|user1,user2| user2.manager <=>
user1.manager}.sort_by{|user| user.name}
#dishes=(Dish.joins(obligations: {participation: :feast}).where(feast:
{id:#feast.id }).to_a + #feast.dishes).compact
end
def delete
#feast=Feast.find(params[:id])
end
def destroy
end
private
def feast_params
params.require(:feast).permit(:id, :name, :image, :feast_place,
:feast_time,courses_attributes: [:id,
:dish_id,:_destroy,:feast_id],participations_attributes: [:id,:feast_id,
:user_id, :_destroy],obligations_attributes: [:id, :dish_id, :_destroy,
:participation_id])
end
end
this is the HTML generated:
<form accept-charset="UTF-8" action="/feasts/create" enctype="multipart/form-data"
method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8"
type="hidden" value="✓"><input name="authenticity_token" type="hidden"
value="llJ73mQ6yIZHKvs1EDHnVbjc1nIGlWN2eCirXwiCgCs="></div>
#+> some input fields for the feast goes here
<br><br>
<label for="feast_feast place">feast_place</label><br><br>
<input id="feast_feast_place" name="feast[feast_place]" type="text"> <br><br>
upload image file <br><br>
<input id="feast_image" name="feast[image]" type="file"> <br><br>
<h2>participants
<u>
<a class="right" data-content="<br />
<a class="cl_both" href="#"
onclick="remove_fields(this); return false;">remove</a>
<input id="feast_participations_user_id" name=";feast[participations][user_id]"
type="hidden" />
<input id="feast_participations__destroy" name="feast[participations][_destroy]"
type="hidden" value="false" />
<div data-obcontent='
<input id="feast_participations_obligations_attributes_new_obli_dish_id"
name="feast[participations][obligations_attributes][new_obli][dish_id]"
type="hidden"/>
<input id="feast_participations_obligations_attributes_new_obli__destroy"
name="feast[participations][obligations_attributes][new_obli][_destroy]"
type="hidden" value="false" />
' >
</div>
" href="#" id="try" onclick="add_par(); return false;">
<img alt="Photo Gallery" height="100" src="/assets/add_participants.png"
width="100">
</a> </u>
</h2>
<br><br><br>
<div data-myid="3" data-myimage=""image":{"url:"/uploads/user/image/3/el4.jp"}}" data-
myname="elad bezalel" id="par">
<table>
<tbody><tr>
<th>participant</th>
<th>assignment</th>
</tr>
<tr><td><div class="user_block ui-droppable" style=""><a href="/users/show?
id=7" id="1404733550784"><img alt="user picture"
src="/uploads/user/image/7/Yemenite.gif" height="100" width="100">
<br>amit</a><br>
<a class="cl_both" href="#" onclick="remove_fields(this); return
false;">remove</a>
<input id="1404733550977" name="feast[participations][user_id]"
type="hidden" value="7">
<input id="1404733554049" name="feast[participations]
[obligations_attributes][1404733554050][dish_id]" type="hidden"
value="140473354199">
<input id= "feast_participations_obligations_attributes_1404733554050__destroy"
name="feast[participations][obligations_attributes][1404733554050][_destroy]"
type="hidden" value="false">
<input id="feast_participations__destroy" name="feast[participations]
[_destroy]" type="hidden" value="false">
<div data-obcontent="
<input id="feast_participations_obligations_attributes_new_obli_dish_id"
name="feast[participations][obligations_attributes][new_obli][dish_id]"
type="hidden" ></div>
<input id="feast_participations_obligations_attributes_new_obli__destroy"
name="feast[participations][obligations_attributes][new_obli][_destroy]"
type="hidden" value="false" />
">
</div>
</div></td><td><dfn>e </dfn><img
alt="cancel - x" class="x-pic" height="30" src="/assets/x-blue.png" width="30">
</td></tr></tbody></table>
</div>
<br><br><br><br><br><br>
<h2>dishes
<u>
<a class="right" data-content="<br />
<a class="cl_both" href='#' onclick='remove_fields_dish(this); return
false'>remove</a>
<input id="feast_courses_dish_id" name="feast[courses][dish_id]" type="hidden" />
<input id="feast_courses__destroy" name="feast[courses][_destroy]"type="hidden"
value="false" />
" href="#" id="add_course" onclick="add_course(); return false;">
<img alt="Photo Gallery" height="100" src="/assets/add_dish.png" width="100">
</a> </u>
</h2>
<br><br><br>
<div id="course">
<table>
<tbody><tr><td><div class="dish_block ui-draggable ui-draggable-handle"
style="position: relative; top: 0px; left: 0px;"><a href="/dishes/show?id=9"
id="1404733541991"><img alt="dish picture"
src="/uploads/dish/image/9/IMG_0012.JPG" height="100" width="100"><br>e</a><br>
<a class="cl_both" href="#" onclick="remove_fields_dish(this); return
false;">remove</a>
<input id="1404733542182" name="feast[courses][dish_id]" type="hidden" value="9">
<input id="feast_courses__destroy" name="feast[courses][_destroy]" type="hidden"
value="false">
</div></td></tr></tbody></table>
</div>
<br><br>
<input name="commit" type="submit" value="initiate feast">
</form>
why does the nested parts not save?
I don't know the problem, but here are some things I would do to debug and narrow down your issue:
In your controller, raise feast_params.inspect. Do that match your expectations?
In a rails console session, try to create nested models (Feast.new(participations_attributes: {...})).
so here it goes:
i tried 2 plugins and they didn't work so i figured that i am doing something wrong with the
general form.
i used matched routes . as i changed to REST routes everything works fine.
probebly the previous form decleration line :
<%= form_for(:feast, :url => {:action => 'create'}) do |f| %>
was lacking the #feast variable so it can append to it the nested parts.
so maybe there is a way to fix it even with matched routes maybe something like:
<%= form_for(:feast, #feast, :url => {:action => 'create'}) do |f| %>
but since
i change to REST routes its working and i don't bother to check.
Related
I have a set up where Goals have Steps and Steps have Tasks. In my view I am showing a goal, if that goal has steps then I can pull those and show them as well. I am having a hard time showing the tasks for each individual step now. I can get the task associated with the proper step so part of this is working, but I cannot access any of the data, name and description specifically for the task.
I am just unsure how to create this in the controller. I have cruised around the guide trying to find a solution and tried things like
#goal.steps.tasks
#step.tasks
I just cannot find anything that clicks for creating the variable in the controller so I can access it.
goals_controller.rb show method
def show
#goal = Goal.find(params[:id])
#steps = #goal.steps(page: params[:page])
# #tasks = ?
end
goal.rb
class Goal < ActiveRecord::Base
has_many :steps, dependent: :destroy
has_many :tasks, through: :steps
end
step.rb
class Step < ActiveRecord::Base
belongs_to :goals
has_many :tasks, dependent: :destroy
default_scope -> { order(created_at: :desc) }
end
task.rb
class Task < ActiveRecord::Base
belongs_to :steps
end
views
goals/show view
<p>
<% if #goal.steps.any? %>
<!-- Projects Row -->
<div class="row">
<%= render #steps %>
</div>
<!-- /.row -->
<% else %>
No steps for this goal.
<% end %>
</p>
the partial rendered for the steps
<div id="steps-<%= step.id %>" class="col-md-3 portfolio-item not completed" style="background-color:#e26a5c;border-radius:10px;border:1px solid #6cbdc4;margin:0 5px 5px 0;">
<h3>
<p>In order to achieve this goal I need to <strong><%= step.name %></strong> in <strong><%= time_ago_in_words(step.deadline) %></strong></p>
</h3>
<img src="/img/icon-edit.png">
<% if step.tasks.any? %>
<%= render "tasks/task" %>
<% else %>
<%end %>
</div>
<% else %>
<div id="steps-<%= step.id %>" class="col-md-3 portfolio-item completed" style="background-color:#6cbdc4;border-radius:10px;border:1px solid #e26a5c;margin:0 5px 5px 0;">
<h3>
<p>In an effort to achieve this goal I needed to <strong><%= step.name %></strong> in <strong><%= time_ago_in_words(step.deadline) %></strong></p>
</h3>
<img src="/img/icon-edit.png">
</div>
Tasks/task is the partial I am trying to pull in, I can link to it on the correct step and everything, but it says undefined method when I put task.name or task.description in.
Try this in your goals_controller.rb:
def show
#goal = Goal.find(params[:id])
#steps = #goal.steps(page: params[:page]).includes(:tasks)
end
Then in your view you could have something like this:
<ul>
<% #steps.each do |step| %>
<li>
<%= step %>
<p>Tasks:</p>
<ul>
<% step.tasks.each do |task| %>
<li><%= task %></li>
<% end %>
</ul>
</li>
<% end %>
</ul>
For more info on includes: http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations
Newbie on RoR. I want to search division, category and brand (by name, not by id). I have a problem to figure out a search function. Hopefully I can get out from my problem. What should I do to convert (division_id) --> (division_name), etc?
**#Model**
item.rb :
belongs_to :division
belongs_to :category
belongs_to :brand
def self.search(params)
items = Item.all
items = items.where("division_id BETWEEN #{params[:division_from].to_i} AND #{params[:division_to].to_i}") if params[:division_from].present?
items = items.where("category_id BETWEEN #{params[:category_from].to_i} AND #{params[:category_to].to_i}") if params[:category_from].present?
items = items.where("brand_id BETWEEN #{params[:brand_from].to_i} AND #{params[:brand_to].to_i}") if params[:brand_from].present?
end
category.rb :
has_many = items
division.rb :
has_many = items
brand.rb :
has_many = items
**#View**
items- index.html.erb
<fieldset><legend>Filter</legend></fieldset>
<div class="panel-body">
<div class="row">
<%= form_tag search_items_path, class: "form-horizontal bucket-form", remote: true do %>
<div class="col-md-6">
<div class="form-group">
<div class="text-field">
<div class="col-md-10">
<td>Division</td>
<div class="input-group input-large">
<%= text_field_tag 'division_from','', class: "form-control dpd1" %>
<span class="input-group-addon">To</span>
<%= text_field_tag 'division_to','', class: "form-control dpd1" %>
</div>
<td>Category</td>
<div class="input-group input-large">
<%= text_field_tag 'category_from','', class: "form-control dpd1" %>
<span class="input-group-addon">To</span>
<%= text_field_tag 'category_to','', class: "form-control dpd1" %>
</div>
<td>Brand</td>
<div class="input-group input-large">
<%= text_field_tag 'brand_from','', class: "form-control dpd1" %>
<span class="input-group-addon">To</span>
<%= text_field_tag 'brand_to','', class: "form-control dpd1" %>
</div>
<div class="btn-group">
<%= submit_tag 'Search', class: "btn btn-primary" %>
</div>
</div>
</div>
</div>
</div>
<% end %>
</div>
</div>
**#Controller**
items_controller.rb :
def search
#items = Item.search(params)
respond_to do |format|
format.js
end
end
If I execute my code, I have search by id (not by name).. Thanks before
Well.. first, if you want to search only one division-category-brand, change the view for every item only one text input (but its better to use select/multiselect).
Using text input:
only one text input per class
e.g. <%= text_field_tag 'brand','', class: "form-control dpd1" %>
in the item.rb change the search method to this
def self.search(params)
items = Item.all
items = items.where(division_id:Division.find_by_name(params[:division])) if params[:division].present?
items = items.where(category_id:Category.find_by_name(params[:category])) if params[:category].present? items = items.where(brand_id:Brand.find_by_name(params[:brand])) if params[:division].present?
end
It will not work when you're not filling the correct name in the view, so i suggest to use select/multiselect.
I hope it will work.
Like others working with Stripe payments, I was getting an error 'Cannot charge a customer that has no active card'. The form was not appending the token because the javascript did not have a matching id in the form, but now I am getting an rails error and the card is not being charged, the customer is created, the error states that there is an invalid line item, when the code to create the customer and charge the card is not run the order is created without error.
Order View
<script type="text/javascript" src="https://js.stripe.com/v2/">
$(function(){
Stripe.setPublishableKey('<%= Rails.configuration.stripe[:PUBLISHABLE_KEY] %>');
});
</script>
<div class = "Power Me" >
<fieldset>
<legend> Please enter your details </legend>
<%= render 'form', object: #object %>
</fieldset>
</div>
Rendered Order Form
<%= form_for(#order, :html => {:id => 'payment-form'}) do |f| %>
<% if #order.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#order.errors.count, "error") %> prohibited this order from being saved:</h2>
<ul>
<% #order.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= "Order Total: #{order_total.to_s}" %>
<%= "Order Currency: #{order_currency.to_s}" %>
</div>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :Address_line_1 %><br>
<%= f.text_area :address_line_1 %>
</div>
<div class="field">
<%= f.label :Address_Line_2 %><br>
<%= f.text_area :address_line_2 %>
</div>
<div class="field">
<%= f.label :City %><br>
<%= f.text_area :address_city %>
</div>
<div class="field">
<%= f.label :Region %><br>
<%= f.text_area :address_state %>
</div>
<div class="field">
<%= f.label :Postcode %><br>
<%= f.text_area :address_zip %>
</div>
<div class="field">
<%= f.label :Country %><br>
<%= f.select :address_country, Order::CC_COUNTRIES, prompt: 'Select the country' %>
</div>
<div class="field">
<%= f.label :email %><br>
<%= f.text_field :email, :placeholder => "you#example.com" %>
</div>
<div class="field">
<%= f.label :Payment_Type %><br>
<%= f.select :pay_type, Order::PAYMENT_TYPES, prompt: 'Select a payment method' %>
</div>
<div class="form-row">
<label>Card Number</label>
<input type="text" size="20" autocomplete="off" data-stripe="number" id="number" class="credit-number", placeholder = "**** **** **** ****" pattern="[\d ]*" />
</div>
<div class="form-row">
<label>Security Code/CVC</label>
<input type="text" size="4" autocomplete="off" data-stripe="cvc" id="cvc" class="credit-scurity" placeholder="***" pattern="\d*" />
</div>
<div class="form-row">
<label>Expiration (MM/YYYY)</label>
<input type="text" size="2" data-stripe="exp-month" id="exp-month" class="card-expiry-month" placeholder="MM" pattern="\d*" />
<span> / </span>
<input type="text" size="4" data-stripe="exp-year" id="exp-year" class="card-expiry-year" placeholder="YYYY" pattern="\d*" />
</div>
<div class="actions">
<%= f.submit 'Pay', :class =>"stripe-button" %>
</div>
<% end %>
orders model
class Order < ActiveRecord::Base
# attr_accessor :stripeToken
PAYMENT_TYPES = ["credit card"]
CC_COUNTRIES = ["United Kingdom", "France", "Italy"]
validates :name, :address_line_1, :address_zip, :email, presence: true
# validates :pay_type, inclusion: PAYMENT_TYPES
has_many :line_items, dependent: :destroy
def add_line_items_from_cart(cart)
cart.line_items.each do |item|
item.cart_id = nil
line_items << item
end
end
end
Orders Controller
class OrdersController < ApplicationController
include CurrentCart
before_action :set_cart, only: [:new, :create]
before_action :set_order, only: [:show, :edit, :update, :destroy]
# GET /orders
# GET /orders.json
def index
#orders = Order.all
end
# GET /orders/1
# GET /orders/1.json
def show
end
# GET /orders/new
def new
if #cart.line_items.empty?
redirect_to store_url, notice: "Your cart is empty"
return
end
#order = Order.new
end
# GET /orders/1/edit
def edit
end
# POST /orders
# POST /orders.json
def create
#order = Order.new(order_params)
#order.add_line_items_from_cart(#cart)
respond_to do |format|
if #order.save
Cart.destroy(session[:cart_id])
session[:cart_id] = nil
format.html { redirect_to #order, notice: 'Order was successfully created.' }
format.json { render action: 'show', status: :created, location: #order }
else
format.html { render action: 'new' }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
Stripe.api_key = "sk_test_BsdqHq0SQuPqHIsm46lcpX4v"
#amount = order_total.to_i * 100
token = params[:stripeToken]
=begin
begin
customer = Stripe::Customer.create(
:email => order_params[:email]
)
charge = Stripe::Charge.create(
:customer => customer.id,
:amount => #amount, # amount in cents, again
:currency => order_currency,
:card => token,
:description => order_params[:email]
)
redirect_to root_path
rescue Stripe::CardError => e
#error = e
end
=end
end
# PATCH/PUT /orders/1
# PATCH/PUT /orders/1.json
def update
respond_to do |format|
if #order.update(order_params)
format.html { redirect_to #order, notice: 'Order was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
end
# DELETE /orders/1
# DELETE /orders/1.json
def destroy
#order.destroy
respond_to do |format|
format.html { redirect_to orders_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_order
#order = Order.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def order_params
params.require(:order).permit(:name, :email, :pay_type, :address_line_1, :address_line_2, :address_city, :address_state, :address_zip, :address_country)
end
end
My Application Helper
module ApplicationHelper
def order_total
total = LineItem.joins(:product).select("sum(line_items.quantity * products.price) as total").where("cart_id = ?", session[:cart_id]).first.total
end
def order_currency
currency = LineItem.joins(:product).joins(:currency).select("currencies.name as iso_name").where("cart_id = ?", session[:cart_id]).first.iso_name
end
# Returns the full title on a per-page basis.
def full_title(page_title)
base_title = "Ruby on Rails Tutorial Sample App"
if page_title.empty?
base_title
else
"#{base_title} | #{page_title}"
end
end
def bootstrap_class_for flash_type
{ success: "alert-success", error: "alert-danger", alert: "alert-warning", notice: "alert-info" }[flash_type] || flash_type.to_s
end
def flash_messages(opts = {})
flash.each do |msg_type, message|
concat(content_tag(:div, message, class: "alert #{bootstrap_class_for(msg_type)} fade in") do
concat message
end)
end
nil
end
# before filters
def signed_in_user
unless signed_in?
store_location
redirect_to signin_url, notice: "Please sign in."
end
end
def correct_user
#user = User.find(params[:id])
redirect_to(root_url) unless current_user?(#user)
end
def admin_user
redirect_to(root_url) unless current_user.admin?
end
end
Orders.js
$('#payment-form').submit(function(event) {
var form = $(this);
form.find('button').prop('disabled', true);
Stripe.createToken(form, stripeResponseHandler);
return false;
});
Working Order Form below, you cannot pass fields to Stripe and use them in the rails form to save in the db, its either or (previous example attempted to save address fields in the db and pass them to stripe as part of the transaction validation.
<%= form_for(#order, :html => {:id => 'payment-form'}) do |f| %>
<% if #order.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#order.errors.count, "error") %> prohibited this order from being saved:</h2>
<ul>
<% #order.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= "Order Total: #{order_total.to_s}" %>
<%= "Order Currency: #{order_currency.to_s}" %>
</div>
<div class="form-row">
<label>Full Name</label>
<input type="text" size="20" autocomplete="off" data-stripe="name" />
</div>
<div class="field">
<%= f.label :email %><br>
<%= f.text_field :email, :placeholder => "you#example.com" %>
</div>
<div class="field">
<%= f.label :Payment_Type %><br>
<%= f.select :pay_type, Order::PAYMENT_TYPES, prompt: 'Select a payment method', :selected => "credit card" %>
</div>
<div class="form-row">
<label>Address Line 1</label>
<input type="text" size="20" autocomplete="off" data-stripe="address_line1" />
</div>
<div class="form-row">
<label>Address Line 2</label>
<input type="text" size="20" autocomplete="off" />
</div>
<div class="form-row">
<label>Address City</label>
<input type="text" size="20" autocomplete="off" />
</div>
<div class="form-row">
<label>Address State</label>
<input type="text" size="20" autocomplete="off" />
</div>
<div class="form-row">
<label>Zip/Postcode</label>
<input type="text" size="20" autocomplete="off" data-stripe="address_zip" />
</div>
<div class="form-row">
<label>Country</label>
<input type="text" size="20" autocomplete="off" data-stripe="address_country" />
</div>
<div class="form-row">
<label>Card Number</label>
<input type="text" size="20" autocomplete="off" data-stripe="number" placeholder = "**** **** **** ****" pattern="[\d ]*" />
</div>
<div class="form-row">
<label>Security Code/CVC</label>
<input type="text" size="4" autocomplete="off" data-stripe="cvc" placeholder="***" pattern="\d*" />
</div>
<div class="form-row">
<label>Expiration (MM/YYYY)</label>
<input type="text" size="2" data-stripe="exp-month" placeholder="MM" pattern="\d*" />
<span> / </span>
<input type="text" size="4" data-stripe="exp-year" placeholder="YYYY" pattern="\d*" />
</div>
<div class="actions">
<%= f.submit 'Pay', :class => "button" %>
</div>
<% end %>
The form required the id referenced inthe javascript below
var stripeResponseHandler = function(status, response) {
var $form = $('#payment-form');
if (response.error) {
// Show the errors on the form
$form.find('.payment-errors').text(response.error.message);
$form.find('button').prop('disabled', false);
} else {
// token contains id, last4, and card type
var token = response.id;
// Insert the token into the form so it gets submitted to the server
$form.append($('<input type="hidden" name="stripeToken" />').val(token));
// and re-submit
$form.get(0).submit();
}
};
jQuery(function($) {
$('#payment-form').submit(function(e) {
var $form = $(this);
// Disable the submit button to prevent repeated clicks
$form.find('button').prop('disabled', true);
Stripe.card.createToken($form, stripeResponseHandler);
// Prevent the form from submitting with the default action
return false;
});
});
Order Model, fields removed
class Order < ActiveRecord::Base
PAYMENT_TYPES = ["credit card"]
CC_COUNTRIES = ["United Kingdom", "France", "Italy"]
validates :email, presence: true
validates :pay_type, inclusion: PAYMENT_TYPES
has_many :line_items, dependent: :destroy
def add_line_items_from_cart(cart)
cart.line_items.each do |item|
item.cart_id = nil
line_items << item
end
end
end
Application header
<!DOCTYPE html>
<html>
<head>
<title><%= full_title(yield(:title)) %></title>
<%= stylesheet_link_tag "application", media: "all",
"data-turbolinks-track" => true %>
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
<script type="text/javascript">
$(function(){
Stripe.setPublishableKey('<%= Rails.configuration.stripe[:publishable_key] %>');
});
</script>
<%= csrf_meta_tags %>
<%= render 'layouts/shim' %>
</head>
<body>
Order Controller
class OrdersController < ApplicationController
include CurrentCart
before_action :set_cart, only: [:new, :create]
before_action :set_order, only: [:show,:edit, :update, :destroy]
# before_action :admin_user, only: [:destroy, :show]
# GET /orders
# GET /orders.json
def index
#orders = Order.all
end
# GET /orders/1
# GET /orders/1.json
def show
end
# GET /orders/new
def new
if #cart.line_items.empty?
redirect_to store_url, notice: "Your cart is empty"
return
end
#order = Order.new
end
# GET /orders/1/edit
def edit
end
# POST /orders
# POST /orders.json
def create
begin
#order = Order.new(order_params)
#order.add_line_items_from_cart(#cart)
Stripe.api_key = "sk_test_xxxxxxxxxxxxxxx"
#amount = order_total.to_i * 100
token = params[:stripeToken]
# Create a Customer
customer = Stripe::Customer.create(
:description => order_params[:email],
:card => token,
)
charge = Stripe::Charge.create(
:customer => customer.id,
:amount => #amount, # amount in cents, again
:currency => order_currency,
# :card => token,
:description => order_params[:email]
)
respond_to do |format|
if #order.save
puts "saving now"
Cart.destroy(session[:cart_id])
session[:cart_id] = nil
format.html { redirect_to #order, notice: 'Order was successfully created.' }
format.json { render action: 'show', status: :created, location: #order }
else
format.html { render action: 'new' }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to root_path
end
end
# PATCH/PUT /orders/1
# PATCH/PUT /orders/1.json
def update
respond_to do |format|
if #order.update(order_params)
format.html { redirect_to #order, notice: 'Order was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
end
# DELETE /orders/1
# DELETE /orders/1.json
def destroy
#order.destroy
respond_to do |format|
format.html { redirect_to orders_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_order
#order = Order.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def order_params
params.require(:order).permit(:email, :pay_type)
end
end
somehow my form is not working and I dont know why. Heres my code:
<%= simple_form_for #cr, url: edit_cr_path do |f| %>
<hr>
Design Office Involvements<br>
<%= f.collection_check_boxes :design_office_ids, DesignOffice.all, :id, :sub, {:item_wrapper_class => 'checkbox_container'} %>
<hr>
Procurement Involvements<br>
<%= f.collection_check_boxes :procurement_ids, Procurement.all, :id, :sub, {:item_wrapper_class => 'checkbox_container'} %>
<hr>
Installation Involvements<br>
<%= f.collection_check_boxes :installation_ids, Installation.all, :id, :sub, {:item_wrapper_class => 'checkbox_container'} %>
<hr>
<div class="row">
<div class="col-md-6">
Assessment Status
<%= f.input :assessment_status, :collection => [['Impacted','Impacted'],['Not impacted','Not impacted'],['Under assessment','Under assessment'],['New','New']], label: false, selected: ['New', 'New'] %>
</div>
<div class="col-md-6">
<div style="float: right">
<%= f.button :submit, 'Save' %>
</div>
</div>
</div>
<br>
<% end %>
Controller methods looking like this:
class CrsController < ApplicationController
def edit
#cr = Cr.find(params[:id])
end
def update
#cr = Cr.find(params[:id])
#cr.update_attributes(cr_params)
redirect_to edit_cr_path(#cr)
end
private
def cr_params
params.require(:user).permit(:id, :assessment_status)
end
end
And routes like this:
EndToEndManagement::Application.routes.draw do
get '/cr/:id', :to => 'crs#edit', :as => 'edit_cr'
put '/cr/:id', :to => 'crs#update'
patch '/cr/:id', :to => 'crs#update'
end
And thats the html code rails makes of my submit button:
<div class="col-md-6">
<div style="float: right">
<input class="btn" name="commit" type="submit" value="Save" />
</div>
</div>
I think the submit button is not correctly attached to the form but I tried to move it and clear some divs but nothing worked.
Best regards.
EDIT:
Thats what I tested
Removed my routes in routes.rb and replaced it with resources :crs and changed my first line in the form to <%= simple_form_for #cr do |f| %>. Didnt work!
Changed my simple_form to normal form. Didnt work!
Wrote a whole testapp with a scaffold and this form an it worked but I dont know why so I added part by part to my actual app and nothing made it working.
Found my mistake! Not that it would be so mind blowing but I will still post it :D
Had this small mistake in my application.html.erb
<div style="font-size: 1.3em"
<%= yield %>
</div>
Changed it to:
<div style="font-size: 1.3em">
<%= yield %>
</div>
And now it works fine.
It does not seem as edit_cr_path is the right url to go when you're trying to save a form.
You'll need another route:
post '/crs', :to => 'crs#create'
In your view, you probably won't need the url option as Rails can infer just looking at the object.
<%= simple_form_for #cr do |f| %>
But your object needs to be a new instance coming from your controller:
class CrsController < ApplicationController
def new
#cr = Cr.new #or whatever else to initialize the object
end
def create
#save the instance here
end
I've been looking all over the web for an answer to this for the past three hours so I'm going to post a question. I'm trying to create some basic forum software but I am having trouble with my relationships. This is the error I get
undefined method `forums' for # <ActiveRecord::Relation::ActiveRecord_Relation_Category:0x3706cb0>
my categories/index file
<% for category in #category %>
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title"><%= link_to category.name, category_path(category.id) %></h3>
<h4><%= category.description %> </h4>
</div>
<% for forum in #category.forums %>
<div class="panel-body">
<h4><span class="glyphicon glyphicon-tree-conifer"></span><%= link_to forum.name, forum_path(forum.id) %> </h4>
</div>
<hr />
<% end %>
</div>
<% end %>
Categories Controller
class CategoriesController < ApplicationController
def index
#category = Category.all
end
def show
#category = Category.find(params[:id])
end
end
forums controller
class ForumsController < ApplicationController
def show
#forum = Forum.find(params[:id])
end
end
category model
class Category < ActiveRecord::Base
has_many :forums, dependent: :destroy
end
forum model
class Forum < ActiveRecord::Base
belongs_to :category
has_many :threads, dependent: :destroy
end
and my routes
ForumName::Application.routes.draw do
root 'static_pages#home'
resources :users
resources :sessions, only: [:new, :create, :destroy]
resources :categories, :path => "forum"
resources :forums
resources :topics
resources :posts
match '/signup', to: 'users#new', via: 'get'
match '/signin', to: 'sessions#new', via: 'get'
match '/signout', to: 'sessions#destroy', via: 'delete'
end
Hopefully I've provided enough info if anything else is required I'll update the post. Usually I can work these things out using google but this really has me stumped.Thanks in advance.
Issue in action CategoriesController#index
Should be changed to
#categories = Category.all
because Category.all expects to get several categories, not one
Also you should change categories/index file
<% for category in #categories %>
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title"><%= link_to category.name, category_path(category.id) %></h3>
<h4><%= category.description %> </h4>
</div>
<% for forum in category.forums %>
<div class="panel-body">
<h4><span class="glyphicon glyphicon-tree-conifer"></span><%= link_to forum.name, forum_path(forum.id) %> </h4>
</div>
<hr />
<% end %>
</div>
<% end %>