I am getting this error
1 error(s) on assignment of multiparameter attributes
And I am pretty sure it is from the date_selector.
Here is my model
class Order < ActiveRecord::Base
attr_accessor :card_type, :card_number, :card_verification,
:card_expires_on # I do not have these fields in my database
attr_accessible :cart_id, :card_expires_on, :card_type, :first_name,
:ip_address, :last_name,:card_number, :card_verification, :zip, :address,
:state, :city
def credit_card
#credit_card ||= ActiveMerchant::Billing::CreditCard.new(
:brand => card_type,
:number => card_number,
:verification_value => card_verification,
:month => card_expires_on.month,
:year => card_expires_on.year,
:first_name => first_name,
:last_name => last_name
)
end
end
And the part of the controller that is involved
def create
#user = current_user
#cart = current_cart
#order = #cart.build_order(params[:order]) # here is where the error is
#order.user_id = #user.id
#order.ip_address = request.remote_ip
...
end
Here is the cart Model
class Cart < ActiveRecord::Base
has_many :line_items, :dependent => :destroy
has_one :order
belongs_to :user
def add_product(product_id)
current_item = line_items.find_by_product_id(product_id)
if current_item
current_item.quantity += 1
else
current_item = line_items.build(:product_id => product_id)
end
current_item
end
def total_price
line_items.to_a.sum { |item| item.total_price}
end
def total_price_in_cents
return Integer(total_price * 100)
end
end
And heres the order form that goes along with order.rb...Thank you again for the help!!!
<div class="field">
<%= f.label :first_name %><br />
<%= f.text_field :first_name %>
</div>
<div class="field">
<%= f.label :last_name %><br />
<%= f.text_field :last_name %>
</div>
<div class="field">
<%= f.label :address %>
<%= f.text_field :address %>
</div>
<div class="field">
<%= f.label :city %>
<%= f.text_field :city %>
</div>
<div class="field">
<%= f.label :state %>
<%= f.select :state, #order.us_states %>
</div>
<div class="field">
<%= f.label :zip %>
<%= f.text_field :zip %>
</div>
<div class ="field">
<%= f.label :card_type %> <br />
<%= f.select :card_type, [["Visa", "visa"], ["MasterCard", "master"], ["Discover", "discover"], ["American Express", "american_express"]] %>
</div>
<div class="field">
<%= f.label :card_number %><br />
<%= f.text_field :card_number %>
</div>
<div class="field">ry
<%= f.label :card_verification, "Card Verification (CVV)" %><br />
<%= f.text_field :card_verification %>
</div>
<div class="field">
<%= f.label :card_expires_on %><br />
<%= f.date_select :card_expires_on, :discard_day => true, :start_year => Date.today.year, :end_year => (Date.today.year+10), :add_month_numbers => true %>
</div>
<div class="actions">
<%= f.submit %>
</div>
Have you tried #order = #cart.orders.new(params[:order])?
In the case of a one-to-one relationship between an order and a cart, that would be:
#cart.order.new(params[:order])
Related
I created Devise Users table and Type table. I added the type_id column to the users table through migration.
Below are the links in home.html.erb:
<%= link_to 'Basic Sign up', new_user_registration_path(type: #basic_type), class: 'btn btn-success'%>
<%= link_to 'Pro Sign up', new_user_registration_path(type: #pro_type), class: 'button' %>
Below is the pages_controller.rb
class PagesController < ApplicationController
def home
#basic_type = Type.find(1)
#pro_type = Type.find(2)
end
def about
end
end
Below are the models:
type.rb
class Type < ActiveRecord::Base
has_many :users
end
user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
belongs_to :type
end
This is my migration file of type:
class CreateTypes < ActiveRecord::Migration
def change
create_table :types do |t|
t.string :name
t.timestamps
end
end
end
This is the migration file adding types to user:
class AddTypeToUser < ActiveRecord::Migration
def change
add_column :users, :type_id, :integer
end
end
Users table in schema.rb:
create_table "users", force: :cascade do |t|
t.string "email", limit: 255, default: "", null: false
t.string "encrypted_password", limit: 255, default: "", null: false
t.string "reset_password_token", limit: 255
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", limit: 4, default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip", limit: 255
t.string "last_sign_in_ip", limit: 255
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "type_id", limit: 4
end
These are my registration forms:
_basic_form.html.erb:
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: {id: 'basic_type'}) do |f| %>
<%= devise_error_messages! %>
<%= hidden_field_tag 'type', params[:type] %>
<div class="field form-group">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, class: 'form-control' %>
</div>
<div class="field form-group">
<%= f.label :password %>
<% if #validatable %>
<em>(<%= #minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "off", class: 'form-control' %>
</div>
<div class="field form-group">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off", class: 'form-control' %>
</div>
<div class="actions form-group">
<%= f.submit "Sign up", class: 'btn btn-success' %>
</div>
<% end %>
_pro_form.html.erb:
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<%= hidden_field_tag 'type', params[:type] %>
<div class="field form-group">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, class: 'form-control' %>
</div>
<div class="field form-group">
<%= f.label :password %>
<% if #validatable %>
<em>(<%= #minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "off", class: 'form-control' %>
</div>
<div class="field form-group">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off", class: 'form-control' %>
</div>
<div class="actions form-group">
<%= f.submit "Sign up", class: 'btn btn-success', id: 'form-submit-btn' %>
</div>
<% end %>
new.html.erb:
<div class="row">
<div class="col-md-6 col-md-offset-3 text-center">
<% if params[:type] == '2'%>
<h1>Pro Account</h1>
<p>Sign up for the pro account!</p>
<% else %>
<h1>Basic Account</h1>
<p>Sign up for free and get basic access to our community.</p>
<% end %>
</div>
<div class="col-md-6 col-md-offset-3">
<div class="well">
<h2>Sign up</h2>
<% if params[:type] == '2'%>
<%= render "pro_form"%>
<% else %>
<%= render "basic_form"%>
<% end %>
<div class="actions form-group btn btn-default">
<%= render "devise/shared/links" %>
</div>
</div>
</div>
</div>
When I am signing up as basic or as pro in URL it is showing:
http://localhost:3000/users/sign_up?type=1
OR
http://localhost:3000/users/sign_up?type=2
But in database in the type_id column it is showing as nil.
the checkbox helper isn't updating or inserting boolean values in the database.
A label has many attributes with values false as default and should become true when the checkbox is checked.but only the email attribute is being updated.
labelscontroller
def new
#label = current_user.labels.build
end
def create
#label = current_user.labels.build(label_params)
if #label.save
redirect_to #label
else
render 'new'
end
end
def labels_params
params.require(:label).permit(:name,:email,:avatar,:nick,:intro)
end
label/_form.html.erb
<%= form_for #label, :html => { :class => "form-horizontal label" ,multipart: true} do |f| %>
<div class="form-group", style="color: black;">
<%= f.label :name, :class => 'control-label col-lg-2' %>
<div class="col-lg-10">
<%= f.text_field :name, :class => 'form-control' %>
</div>
<%=f.error_span(:name) %>
</div> <div class="form-group", style="color: black;">
<%= f.label :email, :class => 'control-label col-lg-2' %>
<div class="col-lg-10">
<%= f.check_box :email %>
</div>
<%=f.error_span(:email) %>
</div>
<div class="form-group", style="color: black;">
<%= f.label :intro, :class => 'control-label col-lg-2' %>
<div class="col-lg-10">
<%= f.check_box :intro, checked: false %>
</div>
<%=f.error_span(:intro) %>
</div>
<div class="form-group">
<div class="col-lg-offset-2 col-lg-10">
<%= f.submit nil, :class => 'btn btn-primary' %>
<%= link_to t('.cancel', :default => t("helpers.links.cancel")),
labels_path, :class => 'btn btn-default' %>
</div>
</div>
<% end %>
params
developement.rb server logs
database values after the create commit
rails console output of label when i ckecked both email and intro
Pretty new to Ruby, but I'm working on a website for editing information on bus routes for a larger system. The DB has Route separate from it's list of stops, Trips. I'm trying to make the list of stops for each Route easily editable with a list of collection_select forms, where each presents a list of all of the stops to choose from. That was easy with the code below in
routes/_form.html.erb
<!-- handles the list of stops -->
<div class="stops_list" id="stops_list">
<%= f.label "Stops", :class => 'control-label'%>
<% params.merge!(:trips => {}) %>
<% puts params.inspect %>
<% trips = Trip.where('route_id = ?', #route.id).order('trips.order ASC') %>
<% #trips.each do |trip| %>
<%divId = 'stop'+trip[0].to_s %>
<div class="controls" id= <%= divId %>>
<%= f.label trip[0].to_s + '.', :class => 'control-label'%>
<%= collection_select params[:trips], trip[0].to_s, Stop.order('name ASC').all, :id, :name, {:selected => #trips[trip[0]]} %>
</div>
<% end %>
And then I update the proper tables in the DB from the routes_controller based on the data in params. I'd also like to be able to add and remove stops. I tried adding a 'remove stop' button, as below,
<%= button_to_function 'Remove stop',
'if(confirm("Really?")) {
$("#stops_list div").last().remove();
$.get("/routes/removeLastStop/'+(#route.id.to_s)+'");
}'%>
and it removes the proper collection_select form, but I then have to remove the stop from params. I tried doing an ajax call, as you can see, but then I have a new instance of the routes_controller, and the params I want to change is inaccessible. I'm not sure if I just set up the stops list wrong in the first place, or if there's a quick fix, but can anyone more experienced point me in the right direction?
EDIT:
Here's the entire form; it's pretty simple until you reach the area I've added
<%= form_for #route, :html => { :class => 'form-horizontal' } do |f| %>
<div class="control-group">
<%= f.label :name, :class => 'control-label' %>
<div class="controls">
<%= f.text_field :name, :class => 'text_field' %>
</div>
</div>
<div class="control-group">
<%= f.label :longname, :class => 'control-label' %>
<div class="controls">
<%= f.text_field :longname, :class => 'text_field' %>
</div>
</div>
<div class="control-group">
<%= f.label :color, :class => 'control-label' %>
<div class="controls">
<%= f.text_field :color, :class => 'text_field' %>
</div>
</div>
<div class="control-group">
<%= f.label :shape, 'Shape (KML file)', :class => 'control-label' %>
<div class="controls">
<%= f.file_field :shape, :class => 'file_field' %>
</div>
</div>
<div class="control-group">
<%= f.label :enabled, :class => 'control-label' %>
<div class="controls">
<%= f.check_box :enabled, :class => 'checkbox' %>
</div>
</div>
<!-- handles the list of stops -->
<div class="stops_list" id="stops_list">
<%= f.label "Stops", :class => 'control-label'%>
<% params.merge!(:trips => {}) %>
<% puts params.inspect %>
<% trips = Trip.where('route_id = ?', #route.id).order('trips.order ASC') %>
<% #trips.each do |trip| %>
<%divId = 'stop'+trip[0].to_s %>
<div class="controls" id= <%= divId %>>
<%= f.label trip[0].to_s + '.', :class => 'control-label'%>
<%= collection_select params[:trips], trip[0].to_s, Stop.order('name ASC').all, :id, :name, {:selected => #trips[trip[0]]} %>
</div>
<% end %>
<%= button_to_function 'Remove stop',
'if(confirm("Really?")) {
$("#stops_list div").last().remove();
$.get("/routes/removeLastStop/'+(#route.id.to_s)+'");
}'%>
</div>
<!-- adds submit button -->
<div class="form-actions">
<%= f.submit nil, :class => 'btn btn-primary' %>
<%= link_to t('.cancel', :default => t("helpers.links.cancel")),
routes_path, :class => 'btn' %>
</div>
<% end %>
Firstly you can add to Route class:
class Route < ActiveRecord::Base
has_many :trips
end
Firstly i'd like to advise you using decorators, inserting Models in Views is not the best practice.
Secondly you can use gem 'draper' and in RouteDecorator class you can add functions for creating something you want to use or display.
Thirdly you'd better use:
<div class="controls" id="stop<%= trip[0].to_s %>">
Forthly it would be better to use paths in REST-style:
/routes/2/stop/remove
/routes/2/stop/add
Fifthly can you give code of all form?
Probably we need to refactor it to look better and be easier for understanding.
I am new to ruby. I have the same form but i need it to perform creation/updation as and when required. The problem i have now is that whenever i call edit instead of editing the details of an existing user, i am getting a new user with the edited details. To put it simply, i think whenever i perform edit, the create method is being called.
So is there any way to use single form for both new and edit instead of using separate forms.
The following code is for editing user details:
<%= link_to 'Home', root_path %>
<h2>Edit user</h2>
<%= form_for :user, url: user_index_path do |f| %>
<p>
<%= f.label :name %><br>
<%= f.text_field :name %>
</p>
<p>
<%= f.label :address %><br>
<%= f.text_area :address %>
</p>
<p>
<%= f.label :email %><br>
<%= f.text_field :email %>
</p>
<p>
<%= f.label :phone %><br>
<%= f.text_field :phone %>
</p>
<p>
<%= f.label :state %><br>
<%= f.text_field :state %>
</p>
<p>
<%= f.label :country %>
<%= f.collection_select(:country, Country.all, :name, :name) %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
The following code is for creating user:
<%= link_to 'Home', root_path %>
<h2>Create new user</h2>
<%= form_for :user, url: user_index_path do |f| %>
<p>
<%= f.label :name %><br>
<%= f.text_field :name %>
</p>
<p>
<%= f.label :address %><br>
<%= f.text_area :address %>
</p>
<p>
<%= f.label :email %><br>
<%= f.text_field :email %>
</p>
<p>
<%= f.label :phone %><br>
<%= f.text_field :phone %>
</p>
<p>
<%= f.label :state %><br>
<%= f.text_field :state %>
</p>
<p>
<%= f.label :country %>
<%= f.collection_select(:country, Country.all, :name, :name) %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
And this is my controller:
class UserController < ApplicationController
def index
#users = User.all
end
def show
#user = User.find(params[:id])
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
redirect_to #user
else
render 'new'
end
end
def edit
#user = User.find(params[:id])
end
def update
##user = User.find(params[:id])
if #user.update(user_params)
redirect_to #user
else
render 'edit'
end
end
def destroy
#user = User.find(params[:id])
#user.destroy
redirect_to user_index_path
end
private
def user_params
params.require(:user).permit(:name, :address, :email, :phone, :state, :country)
end
end
Since i am new to ruby, i did not get the exact details of how http requests function in ruby.
users/_form.html.erb
<%= link_to 'Home', root_path %>
<%= form_for #user do |f| %>
<p>
<%= f.label :name %><br>
<%= f.text_field :name %>
</p>
<p>
<%= f.label :address %><br>
<%= f.text_area :address %>
</p>
<p>
<%= f.label :email %><br>
<%= f.text_field :email %>
</p>
<p>
<%= f.label :phone %><br>
<%= f.text_field :phone %>
</p>
<p>
<%= f.label :state %><br>
<%= f.text_field :state %>
</p>
<p>
<%= f.label :country %>
<%= f.collection_select(:country, Country.all, :name, :name) %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
users/new.html.erb
<h2>Create new user</h2>
<%= render 'form' %>
users/edit.html.erb
<h2>Edit user</h2>
<%= render 'form' %>
users_controller.rb
class UsersController < ApplicationController
before_filter :find_user, only: [:show, :edit, :update, :destroy]
def index
#users = User.all
end
def show
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
redirect_to #user
else
render 'new'
end
end
def edit
end
def update
if #user.update(user_params)
redirect_to #user
else
render 'edit'
end
end
def destroy
#user.destroy
redirect_to user_index_path
end
private
def user_params
params.require(:user).permit(:name, :address, :email, :phone, :state, :country)
end
def find_user
#user = User.find(params[:id])
end
end
When you have same view code for two or more methods, you should create a partial of same view code and render it in those methods. This is called DRY principle in ruby on rails
I am using gem 'country_select', github: 'stefanpenner/country_select' in my gem file and in my form i have defined it like this:
<%= form_for(#account_detail) do |f| %>
<div class="field">
<%= f.label :city %><br>
<%= f.text_field :city %>
</div>
<div class="field">
<%= f.label :zip %><br>
<%= f.number_field :zip %>
</div>
<div class="field">
<%= f.label :first_name %><br>
<%= f.text_field :first_name %>
</div>
<div class="field">
<%= f.label :last_name %><br>
<%= f.text_field :last_name %>
</div>
<div class="field">
<%= f.label :country %><br>
<%= f.country_select("account_detail", "country") %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
on submit its giving error ActionView::Template::Error (wrong number of arguments (4 for 0)):
Which gem is best to show all countries?
I would use:
<%= f.country_select :country %>
If you like to prioritize some countries in the select pass them in in an array:
<%= f.country_select :country, {priority_countries: %w(<COUNTRY CODE i.e. US>), prompt: 'Select Country'} %>
You can add class: 'your-class' and id or whatever just as with any other field if you like. Hope it helps.
This should do!
<%= f.country_select :country, { priority_countries: ["GB", "US"], selected: "GB" } %>
I have solved this issue by adding this method in my model:
def country_name
country = ISO3166::Country[country_code]
country.translations[I18n.locale.to_s] || country.name
end
and in view change given line :
<%= f.country_select("account_detail", "country") %>
to this:
<%= f.country_select :country, format: :with_alpha2 %>
Hope this will help to someone else who will face this problem.