I'm having a strange issue where an extra/random character ("0") is being displayed with my flash[:notice]. I can't figure out where it's coming from.
Controller:
def edit
#subject = Subject.find_by(id: params[:id])
end
def update
#subject = Subject.find_by(id: params[:id])
if #subject.update_attributes(strong_params)
flash[:notice] = 'Subject has been updated'
redirect_to action: 'show', id: #subject.id
else
render 'edit'
end
end
def delete
#subject = Subject.find_by(id: params[:id])
end
private
def strong_params
params.require(:subject).permit(:name, :position, :visible)
end
View:
= if !flash[:notice].blank?
.notice
= flash[:notice]
%h2 Update subject
= form_for :subject, :url => {action: 'update', id: #subject.id} do |f|
= f.label :name, 'Name:'
= f.text_field :name
= f.label :position, 'Position:'
= f.text_field :position
= f.label :visible, 'Visible:'
= f.text_field :visible
= f.submit 'Update Subject'
%h2
Are you sure you want to delete the subject - #{#subject.name}
= link_to 'Yes, delete!', action: 'destroy', id: #subject.id
So, as it turned out the answer is: change 'loud' haml = if !flash[:notice].blank? to 'silent' - if !flash[:notice].blank?.
Related
hope your having a wonderful day drinking some coffee and responding to some forms.
Problem:
As my title states, I am trying to create 2 forms on one view. I am new to ruby on rails.
My controller functions:
Controller name is border_rotation:
def create
if params[:export_submit]
#border_rotation_export = BorderRotationExport.new(border_rotation_export_params)
respond_to do |format|
if #border_rotation_export.save
flash[:success] = "Export successfully created"
format.html { render :new }
else
flash[:error] = "Export was not created."
end
end
else
#border_rotation_import = BorderRotationImport.new(border_rotation_import_params)
respond_to do |format|
if #border_rotation_import.save
flash[:success] = "Export successfully created"
format.html { render :new }
else
flash[:error] = "Export was not created."
end
end
end
end
def new
#border_rotation_export = BorderRotationExport.new
#border_rotation_import = BorderRotationImport.new
end
private
def border_rotation_export_params
params.require(:border_rotation_export).permit(:exporter_name,:vehicle_color,:rot_num,:current_date,:current_time,:goods_description,:license_num,:entry)
end
def border_rotation_import_params
params.require(:border_rotation_import).permit(:importer_name,:vehicle_color,:rot_num,:current_date,:current_time,:goods_description,:license_num,:entry)
end
My new View form:
It has 2 forms and is enclosed in bootstrap tabs
<%= form_for #border_rotation_export, url: rotation_create_path, method: :post do |f|%>
<lable>Importer Name: </lable><%= f.text_field :importer_name, class: "form-control", placeholder: "Importer Name"%>
<lable>Vehicle Color: </lable><%= f.text_field :vehicle_color, class: "form-control", placeholder: "Vehicle Color"%>
**its fields**
<% end %>
and
<%= form_for #border_rotation_import, url: rotation_create_path, method: :post do |f|%>
<lable>Exporter Name: </lable><%= f.text_field :exporter_name, class: "form-control", placeholder: "Exporter Name"%>
<lable>Vehicle Color: </lable><%= f.text_field :vehicle_color, class: "form-control", placeholder: "Vehicle Color"%>
**its fields**
<% end %>
The error in my new.html.rb
First argument in form cannot contain nil or be empty
Displays this in red highlighted
<%= form_for #border_rotation_export, url: rotation_create_path, method: :post do |f|%>
My guess is that it submits both forms but only has the parameters for one form with the input data. Once I submit, it saves to the database but it gives me the error
**Routes **
get 'rotation/create', to: 'border_rotation#create'
post 'rotation/create', to: 'border_rotation#create'
Request
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"Cu52CIDgrY0b7Yk6edkd7+RTl5yR4qSEqPPrqWtM0nIQVDvw7eYDF36zduJPLjI+vVNqCfgtLcMDUEkW6qDOdQ==",
"border_rotation_import"=>
{"importer_name"=>"john",
"vehicle_color"=>"red",
"rot_num"=>"11sssfeeea",
"current_date"=>"2021-09-22",
"current_time"=>"09:37",
"goods_description"=>"yogurt",
"license_num"=>"c-11223",
"entry"=>"c1223"},
"import_submit"=>"Submit"}
Thank you in advance
You can setup the controller with a lot less redundancy:
# config/routes.rb
resources :rotations, only: [:new, :create]
class BorderRotationsController < ApplicationController
# GET /rotations/new
def new
populate_forms
end
# POST /rotations
def create
resource = model_class.new(create_params)
set_ivar(resource) # sets #border_rotation_export or #border_rotation_import
if resource.save
flash[:success] = "#{humanized} successfully created"
redirect_to action: :new
else
populate_forms
flash[:error] = "#{humanized} could not be created - please try again."
render :new
end
end
private
# gets the model class via params[:subtype]
def model_class
#model_class ||= begin do
if params[:border_rotation_export].present?
BorderRotationExport
else
BorderRotationImport
end
end
end
def humanized
model_class == BorderRotationExport ? 'Export' : 'Import'
end
def set_ivar(value)
instance_variable_set(
"##{param_key}",
value
)
end
# just sets up the instance variables for the form
def populate_forms
#border_rotation_export ||= BorderRotationExport.new
#border_rotation_import ||= BorderRotationImport.new
end
# border_rotation_export or border_rotation_import
def param_key
model_class.model_name.param_key
end
def create_params
require(param_key).permit(
:exporter_name, :vehicle_color, :rot_num,
:current_date,:current_time, :goods_description,
:license_num, :entry
)
end
And then use partials so that you can resuse the same form:
# app/views/border_rotations/new.html.erb
<%= render partial: 'form',
locals: { border_rotation: #border_rotation_export } %>
<%= render partial: 'form',
locals: { border_rotation: #border_rotation_import } %>
# app/views/border_rotations/new.html.erb
<%= form_with model: border_rotation, url: rotations_path do |f| %>
<div class="field">
<%= f.label :importer_name %>
<%= f.text_field :importer_name, class: "form-control" %>
</div>
<div class="field">
<%= f.label :importer_name %>
<%= f.text_field :importer_name, class: "form-control" %>
</div>
# ...
<% end %>
If the requirements diverge use two separate routes/controllers and inheritance instead of blooming out in tons of new code paths.
I am getting an error when I try to update a prop(which is like an article). I can create a prop but when I go to edit it I get the following error:
This is my props controller:
class PropsController < ApplicationController
attr_accessor :user, :answer, :choice, :prop
def index
#props=Prop.all
end
def show
#prop = Prop.find(params[:id])
end
def new
#prop = Prop.new
#user = User.find(session[:user_id])
end
def edit
#prop = Prop.find(params[:id])
#user = User.find(session[:user_id])
#answer = #user.answers.update(prop_params)
end
def create
#prop = Prop.new(prop_params)
#user = User.find(session[:user_id])
#answer = Answer.new
if #prop.save
redirect_to #prop
else
render 'new'
end
end
def update
#user = User.find(session[:user_id])
#prop = Prop.find(params[:prop_id])
#answer = #user.answers.update(answer_params)
if #prop.update(prop_params)
redirect_to #prop
else
render 'edit'
end
if #answer.choice == #prop.choice
puts "hello"
#user.score += 7
#user.save
else
#user.score -= 7
#user.save
end
end
def destroy
#prop = Prop.find(params[:id])
#prop.destroy
redirect_to props_path
end
def select
#prop = Prop.find(params[:choice])
end
end
private
def prop_params
params.require(:prop).permit(:title, :text, :choice, :user_id, :id)
end
def answer_params
params.require(:answer).permit(:choice, :id, :prop_id, :user_id)
end
This is my form. It is a partials shared between the new and edit views:
<%= form_for #prop do |f| %>
<% if #prop.errors.any? %>
<div class="error_explanation">
<h2>
<%= pluralize(#prop.errors.count, "error") %>
prohibited this prop from being saved:
</h2>
<ul>
<% #prop.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :text %><br>
<%= f.text_area :text %>
</p>
<%= f.radio_button(:choice, "A") %>
<%= f.label(:choice, "The Correct Answer is A") %>
<%= f.radio_button(:choice, "B") %>
<%= f.label(:choice, "The Correct Answer is B") %>
<%= f.radio_button(:choice, "C") %>
<%= f.label(:choice, "The Answer Has Yet To Be Determined") %>
<%= f.hidden_field :user_id, :value => #user.id %>
<p>
<%= f.submit %>
</p>
<% end %>
Can you please change your update action as:
def update
#user = User.find(session[:user_id])
#prop = Prop.find(params[:prop_id].merge(:user_id => #user))
#answer = #user.answers.update(answer_params)
if #prop.update(prop_params)
redirect_to #prop
else
render 'edit'
end
if #answer.choice == #prop.choice
puts "hello"
#user.score += 7
#user.save
else
#user.score -= 7
#user.save
end
end
and your prop params as:
def prop_params
params.require(:prop).permit(:title, :text, :choice, :id)
end
This helps in sending the user_id into the prop table by using merge method. Try this I hope this could resolve your issue and make sure you change your create action to send the user_id into prop table.
Ruby version :
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-linux]
Rails version :
Rails 4.1.4
I have a HABTM association between two models : Product and Page. This association works well when I use the console with the following command :
Product.first.pages << Page.first
I inserted a check_box_tag in my products/_form.html.haml for displaying my pages. The check_box works well and I can check/uncheck all my pages.
The problem is when I try to submit the form, the modifications I have done in the checkbox are not saved. I have this problem in both ways.
I figured the problem is the Unpermitted parameters error in my log.
Started PATCH "/admin/pages/linge-de-lit" for 127.0.0.1 at 2014-09-23 23:13:40 +0200
Processing by Admin::PagesController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"q/ZskL+Zijc8GMX9lF+EPgqc9uic9N9B/isWYHx7Cx0=", "page"=>{"category"=>"fabric", "title"=>"Linge de lit", "intro"=>"", "visibility"=>"1", "favorite"=>"0", "priority"=>"50", "product_ids"=>["", "1", "2"]}, "commit"=>"Save", "id"=>"linge-de-lit"}
Page Load (0.3ms) SELECT "pages".* FROM "pages" WHERE "pages"."slug" = 'linge-de-lit' ORDER BY "pages"."id" ASC LIMIT 1
Unpermitted parameters: product_ids
(0.3ms) begin transaction
Page Exists (0.3ms) SELECT 1 AS one FROM "pages" WHERE ("pages"."title" = 'Linge de lit' AND "pages"."id" != 5) LIMIT 1
(0.2ms) commit transaction
Redirected to http://localhost:3000/admin/pages/linge-de-lit
Completed 302 Found in 86ms (ActiveRecord: 1.1ms)
I think the problem is my strong parameters but I doesn't see where.
Here is my models :
class Product < ActiveRecord::Base
has_and_belongs_to_many :pages
end
class Page < ActiveRecord::Base
has_and_belongs_to_many :products
has_many :posts
validates :category, presence: true
validates :title, presence: true, length: {maximum: 20}, uniqueness: true
extend FriendlyId
friendly_id :title, :use => [:slugged, :finders]
before_save :default_values
def default_values
self.title = self.title.capitalize
end
#Scopes
scope :visible, -> { where(visibility: true) }
scope :favorite, -> { where(favorite: true) }
end
Here is my controllers :
class Admin::ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
# GET /admin/products
def index
#products = Product.all
end
# GET /admin/products/1
def show
end
# GET /admin/products/new
def new
#product = Product.new
#pages = Page.all
end
# GET /admin/products/1/edit
def edit
#pages = Page.all
end
# POST /admin/products
def create
#product = Product.new(product_params)
if #product.save
redirect_to [:admin, #product], notice: 'Product was successfully created.'
else
render action: 'new'
end
end
# PATCH/PUT /admin/products/1
def update
if #product.update(product_params)
redirect_to [:admin, #product], notice: 'Product was successfully updated.'
else
render action: 'edit'
end
end
# DELETE /admin/products/1
def destroy
#product.destroy
redirect_to admin_products_url, notice: 'Product was successfully destroyed.'
end
private
# Use callbacks to share common setup or constraints between actions.
def set_product
#product = Product.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def product_params
params.require(:product).permit(:name, :description, :brand_id, :price, :minimum_price, :shop_disponibility, :web_disponibility, :purchase_link, :favorite, {:pages_ids => []})
end
end
class Admin::PagesController < ApplicationController
before_action :set_page, only: [:show, :edit, :update, :destroy]
# GET /admin/pages
def index
#pages = Page.all
end
# GET /admin/pages/1
def show
end
# GET /admin/pages/new
def new
#page = Page.new
#products = Product.all
end
# GET /admin/pages/1/edit
def edit
#products = Product.all
end
# POST /admin/pages
def create
#page = Page.new(page_params)
if #page.save
redirect_to [:admin, #page], notice: 'Page was successfully created.'
else
render action: 'new'
end
end
# PATCH/PUT /admin/pages/1
def update
if #page.update(page_params)
redirect_to [:admin, #page], notice: 'Page was successfully updated.'
else
render action: 'edit'
end
end
# DELETE /admin/pages/1
def destroy
#page.destroy
redirect_to admin_pages_url, notice: 'Page was successfully destroyed.'
end
private
# Use callbacks to share common setup or constraints between actions.
def set_page
#page = Page.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def page_params
params.require(:page).permit(:category, :title, :intro, :visibility, :favorite, :priority, :products_ids => [])
end
end
Here is my views :
# products/_form
= form_for([:admin, #product]) do |f|
- if #product.errors.any?
#error_explanation
%h2= "#{pluralize(#product.errors.count, "error")} prohibited this product from being saved:"
%ul
- #product.errors.full_messages.each do |msg|
%li= msg
.field
= f.label :name
= f.text_field :name
.field
= f.label :description
= f.text_area :description
.field
= f.label :brand_id
= f.text_field :brand_id
.field
= f.label :price
= f.text_field :price
.field
= f.label :minimum_price
= f.check_box :minimum_price
.field
= f.label :shop_disponibility
= f.check_box :shop_disponibility
.field
= f.label :web_disponibility
= f.check_box :web_disponibility
.field
= f.label :purchase_link
= f.text_field :purchase_link
.field
= f.label :favorite
= f.check_box :favorite
= hidden_field_tag "product[page_ids][]", nil
- Page.all.each do |page|
= check_box_tag "product[page_ids][]", page.id, #product.page_ids.include?(page.id), id: dom_id(page)
= label_tag dom_id(page), page.title
.actions
= f.submit 'Save'
# pages/_form
= form_for([:admin, #page]) do |f|
- if #page.errors.any?
#error_explanation
%h2= "#{pluralize(#page.errors.count, "error")} prohibited this page from being saved:"
%ul
- #page.errors.full_messages.each do |msg|
%li= msg
.field
= f.label :category
= f.select :category, options_for_select(#pages_categories), {:prompt => "- Sélectionner une catégorie -"}
.field
= f.label :title
= f.text_field :title
.field
= f.label :intro
= f.text_area :intro
.field
= f.label :visibility
= f.check_box :visibility
.field
= f.label :favorite
= f.check_box :favorite
.field
= f.label :priority
= f.number_field :priority
= hidden_field_tag "page[product_ids][]", nil
- Product.all.each do |product|
= check_box_tag "page[product_ids][]", product.id, #page.product_ids.include?(product.id), id: dom_id(product)
= label_tag dom_id(product), product.name
.actions
= f.submit 'Save'
There is a typo there :) Instead of
# Only allow a trusted parameter "white list" through.
def page_params
params.require(:page).permit(:category, :title, :intro, :visibility, :favorite, :priority, :products_ids => [])
end
It should be product_ids:
# Only allow a trusted parameter "white list" through.
def page_params
params.require(:page).permit(:category, :title, :intro, :visibility, :favorite, :priority, :product_ids => [])
end
I'm trying to pass an order and transfer the money to a recipient which created the listing.
Every time i try to pass an order i get a error "Cannot transfer to a recipient that has no default payment account". When a user makes a new listing they must provide information like Country, Routing Number and Account Number only ones. I will show my code and if anybody can see an error i did it would help a lot.
When i try this in the console this is what i get
rp = Stripe::Recipient.retrieve(user.recipient)
=> #<Stripe::Recipient:0x8333f120 id=rp_14X1Sz4SnElBeDRiOQWxitGL> JSON: {
"id": "rp_14X1Sz4SnElBeDRiOQWxitGL",
"object": "recipient",
"created": 1409365189,
"livemode": false,
"type": "individual",
"description": null,
"email": "perez#mezarina.me",
"name": "Andy Perez",
"verified": false,
"metadata": {},
"active_account": null,
"cards": {"object":"list","total_count":0,"has_more":false,"url":"/v1/recipients/rp_14X1Sz4SnElBeDRiOQWxitGL/cards","data":[]},
"default_card": null
}
This is my Listings controller
class ListingsController < ApplicationController
def index
if params[:query].present?
#listings = Listing.search(params[:query], page: params[:page])
else
#listings = Listing.all.order("created_at desc").limit(12)
end
end
def show
#listing = Listing.find(params[:id])
end
def new
#listing = Listing.new
end
def create
#listing = Listing.new(listing_params)
#listing.user_id = current_user.id
if current_user.recipient.blank?
Stripe.api_key = ENV["STRIPE_API_KEY"]
token = params[:stripeToken]
recipient = Stripe::Recipient.create(
:name => #listing.user.name,
:email => #listing.user.email,
:type => "individual",
:bank_account => token
)
current_user.recipient = recipient.id
current_user.save
end
if #listing.save
redirect_to #listing
else
render :new
end
end
def seller
#listing = Listing.where(user: current_user)
end
def favorite
if #listing = Listing.find(params[:id])
current_user.mark_as_favorite #listing
redirect_to #listing
end
end
def unfavorite
#listing = Listing.find(params[:id])
#listing.unmark :favorite, :by => current_user
redirect_to #listing = :back
end
private
def listing_params
listing_params = params.require(:listing).permit(:name, :description, :price, :image, :anime_id).merge(:user_id => current_user.id)
end
end
This is my orders controller
class OrdersController < ApplicationController
def sales
#orders = Order.all.where(seller: current_user)
end
def purchases
#orders = Order.all.where(buyer: current_user)
end
def new
#order = Order.new
#listing = Listing.find(params[:listing_id])
end
def create
#order = Order.new(order_params)
#listing = Listing.find(params[:listing_id])
#seller = #listing.user
#order.listing_id = #listing.id
#order.buyer_id = current_user.id
#order.seller_id = #seller.id
recipient_id = #listing.user.recipient
Stripe.api_key = ENV["STRIPE_API_KEY"]
token = params[:stripeToken]
begin
charge = Stripe::Charge.create(
:amount => (#listing.price * 100).floor,
:currency => "usd",
:card => token
)
flash[:notice] = "Thanks for ordering!"
rescue Stripe::CardError => e
flash[:danger] = e.message
end
transfer = Stripe::Transfer.create(
:amount => (#listing.price * 95).floor,
:currency => "usd",
:bank_account => token,
:recipient => #seller.recipient
)
if #order.save
redirect_to root_path
else
render :new
end
end
private
def set_order
#order = Order.find(params[:id])
end
def order_params
order_params = params.require(:order).permit(:address, :city, :state, :buyer_id, :seller_id)
end
end
New listing form
<section class="new-listing">
<div class="row">
<div class="medium-3 medium-centered columns end">
<%= simple_form_for #listing do |f| %>
<%= f.file_field :image %>
<%= f.input :name, placeholder: 'Name',label: false %>
<%= f.input :price, placeholder: 'Price in USD',label: false %>
<%= f.association :anime, prompt: 'Pick anime',label: false %>
</div>
<div class="medium-12 columns description">
<%= f.input :description, :input_html => { :cols => 50, :rows => 10 }, label: false, placeholder: 'Write the product description here......' %>
<% if current_user.recipient.blank? %>
<br>
<h1>Bank Account Information</h1>
<div class="form-group">
<%= label_tag :country %>
<%= text_field_tag :country, nil, { :name => nil, :'data-stripe' => "country" } %>
</div>
<div class="form-group">
<%= label_tag :routing_number %>
<%= text_field_tag :routing_number, nil, { :name => nil, :'data-stripe' => "routingNumber"} %>
</div>
<div class="form-group">
<%= label_tag :account_number %>
<%= text_field_tag :account_number, nil, { :name => nil, :'data-stripe' => "accountNumber"} %>
</div>
<% end %>
<div class="medium-1 medium-centered columns end">
<%= f.submit 'Done', class: 'button tiny' %>
</div>
<% end %>
</div>
The console code you're showing also reflects that there's no account setup for the recipient (to which we'd transfer funds). Hence, the error message. I don't see anywhere in your code where you're creating the destination account (e.g., bank or debit card).
Also, just to be clear, if you process a charge today, those funds won't be available for transfer until X days later (X = depends upon your account).
Hope that helps,
Larry
PS I work on Support at Stripe.
I want to show errors when they are in form and can not understand why this code does not work.
hotel.rb
class Hotel < ActiveRecord::Base
...
has_many :comments
...
end
comment.rb
class Comment < ActiveRecord::Base
belongs_to :hotel
belongs_to :user
delegate :email, to: :user, prefix: true
validates :body, presence: true, length: { minimum: 5, maximum:200 }
end
hotels/show.
...
%h2 Comments
#comments
.ui.piled.blue.segment
.ui.header
%i.icon.inverted.circular.blue.comment
Comments
.ui.comments
= render :partial => #hotel.comments
= render 'comments/form', comment: #hotel.comments
...
_form
-if user_signed_in?
= simple_form_for [#hotel, Comment.new] do |f|
=f.error_notification
%br
.ui.reply.form
.field
=f.label :body, "New comment"
=f.input :body, as: :text, label: false
=f.submit 'Add comment', class: "ui fluid blue labeled submit icon button"
-else
=link_to 'Sign in to add comment', new_user_session_path, class: 'ui blue button'
_comment
= div_for comment do
.comment
.content
%span.author= comment.user_email
.metadata
%span.date Posted #{time_ago_in_words(comment.created_at)} ago
.text
= comment.body
If you add too_short and too_long model that does not correct the.
UPDATE
comments_controller
class CommentsController < ApplicationController
def create
#hotel = Hotel.find(params[:hotel_id])
#comment = #hotel.comments.new(comment_params)
#comment.user_id = current_user.id
#comment.save
redirect_to #hotel
end
private
def comment_params
params.require(:comment).permit(:user_id, :body, :hotel_id)
end
end
I solved this problem.
comments_controller
def create
#hotel = Hotel.find(params[:hotel_id])
#comment = #hotel.comments.new(comment_params)
#comment.user_id = current_user.id
#comment.save
respond_to do |format|
if #comment.save
format.html { redirect_to #hotel }
else
format.html { render partial: 'comments/form' }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
_form
-if user_signed_in?
= simple_form_for [#hotel, #comment] do |f|
- if #comment.errors.any?
#error_explanation
%h2
= pluralize(#comment.errors.count, "error")
prohibited this comment from being saved:
%ul
- #comment.errors.full_messages.each do |msg|
%li= msg
%br
.ui.reply.form
=f.error_notification
.inputs
=f.label :body, "New comment"
=f.input :body, as: :text, label: false
.actions
=f.button :submit, 'Add comment', class: "ui fluid blue labeled submit icon button"
-else
=link_to 'Sign in to add comment', new_user_session_path, class: 'ui blue button'
%br
This code render comment form when the comment doesn't save, and write the errors.
Your issue is in your controller. Error's won't populate until you try and save the record. Well in your instance you don't have any flow control to see if it saved, you just have #comment.save. If it doesn't save or if it does save, you do the same redirect.
Try this:
if #comment.save
redirect_to #hotel, notice: 'Comment was successfully created.'
else
redirect_to #hotel, notice: 'There was an issue trying to save your comment.'
end
Now with render :new, #comment.errors will be populated (assuming you tried an invalid length) and now you should see the error messages displayed!