I have two tables Users and Incomes. User has an id column and Income has a foreign key of user_id that is referencing User's id column. The association has been created in the model: User will has_many incomes and income belongs_to user. I want the new.html.erb in the income model to submit a new income item and set its foreign key to the session's current user's id without the user put in id in the form(that means user must sign in with his/her account).
Here is my application controller:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
private
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
helper_method :current_user #make the private method to be accessible for the view
end
end
Here is my new.html.erb for the income model:
<h1>Add New Income</h1>
<div class="field">
<%= form_tag %>
<%= label_tag :title %>
<%= text_field :title, params[:title] %>
<%= label_tag :amount %>
<%= number_field :amount, params[:amount] %>
<br>
<% if current_user %>
User ID:<%= current_user.id %>
User Name: <%= current_user.user_name %>
<% :user_id = current_user.id%>
<% end %>
<%= submit_tag "Submit" %>
Try
<%= form_for(#income, :html =>{:class => "form "}) do |f| %>
<%= label_tag :title %>
<%= text_field :title, params[:title] %>
<%= label_tag :amount %>
<%= number_field :amount, params[:amount] %>
<br>
<% if current_user %>
User ID:<%= current_user.id %>
User Name: <%= current_user.user_name %>
<%= f.hidden_field :user_id, value: current_user.id%>
<% end %>
<%= submit_tag "Submit" %>
<% end %>
Related
My project has 2 models, Company and Product. Company has many products and products belongs to company. I want to put a link to Product's new action on a Company show page and pass company_id to Product new action so that the new product automatically belongs to the company from which it linked.
How should I change below codes to make this happen?
My environment is ruby 2.0.0 and rails 4.0.2
show.html.erb(Companies)
<%= link_to "Add new product", new_product_path(company_id: #company) %>
products_controller.rb
def new
#product = Product.new(params[:company_id])
end
def create
#product = Product.new(product_params, params[:company_id])
if #product.save
flash[:success] = "Product successfully created."
redirect_to #product
else
render 'new'
end
end
new.html.erb(products)
<% provide(:title, 'New product') %>
<h1>Add a new product</h1>
<div class="row">
<div class="span6 offset3">
<%= form_for(#product) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :name, "Product Name" %>
<%= f.text_field :name %>
<%= f.label :description, "Description" %>
<%= f.text_area :description %>
<%= f.label :type, "Product Type" %>
<%= f.text_field :type %>
<%= f.label :released_date, "Released Date" %>
<%= f.date_field :released_date %>
#I want to omit below 2 lines by passing company_id from company show action
<%= f.label :company_id, "Company ID" %>
<%= f.text_field :company_id %>
<%= f.submit "Submit", class: "btn btn-large btn-primary" %>
<% end %>
</div>
</div>
:comapny_id is passed to product new action as shown in URL.
http://localhost:3000/products/new?company_id=6
Also shown in debug log.
company_id: '6'
action: new
controller: products
I think your error lies in the way you create the new product in the new action. At the moment it only passes the company id itself to the constructor, but you are not telling rails wich property should be set with it.
If you change it to #product = Product.new(company_id: params[:company_id]), then your new product object should have the company id and it should be filled in in the create form. Then, instead of omitting the fields you could just use a hidden field. Like this, there is no extra field for the company_id but it is still automatically added to the product_params and #product = Product.new(product_params) will create a product with a company_id.
I need to save many items to Cart on form, user enter quantity one form, and selected items goes to db, but now save only first entered quantity of item. Why?
my form
<%= form_for #cart_item do |f| %>
<% #category.items.each do |item| %>
<%= item.name %>
<%= f.hidden_field :item_id, :value => item.id %>
<%= f.text_field :qty %>
<% end %>
<%= f.submit %>
<% end %>
And controller
cart_items_controller.rb
class CartItemsController < ApplicationController
before_action :set_cart, only: [:create]
def create
#cart_items = CartItem.create(cart_items_params)
#cart_items.cart_id = #cart.id
if #cart_items.save
redirect_to :back
else
render root_path
end
end
private
def cart_items_params
params.require(:cart_item).permit(:id, :qty, :item_id, :cart_id)
end
def set_cart
#cart = Cart.find(session[:cart_id])
rescue ActiveRecord::RecordNotFound
#cart = Cart.create
session[:cart_id] = #cart.id
end
end
There are a few problems here. I'll give you a little bump:
<% #category.items.each do |item| %>
<%= item.name %>
<%= f.hidden_field :item_id, :value => item.id %>
<%= f.text_field :qty %>
<% end %>
For each CartItem, this is going to create an input like this
<input name="qty">
This is problematic because only one (the last one in the DOM) will be submitted. You need to research fields_for and incorporate that into your loop in order to get unique names for each Item in the form.
This same issue follows through into your controller
def cart_items_params
params.require(:cart_item).permit(:id, :qty, :item_id, :cart_id)
end
This is going to look for a single :id, :qty, :item_id, and :cart_id, when in reality you're looking to accept multiple :item_id and :qty fields. You need to research Strong Parameters with nested has_many associations.
Finally you have this
#cart_items = CartItem.create(cart_items_params)
which is going to attempt to create a single CartItem when you're really trying to create multiple items and associate them back to the Cart. You need to research accepts_nested_attributes_for as well as more generally "rails form save has_many association". It's a widely covered topic here on SO and elsewhere.
I do this:
def create
#cart_items = params[:cart_items]
#cart_items.each do |c|
#cart_item = CartItem.new(c)
if #cart_item.qty.present?
#cart_item.cart_id = #cart.id
#cart_item.save
end
end
and form
<%= form_tag cart_items_path do %>
<% #cart_items.each do |cart_item| %>
<%= fields_for "cart_items[]", cart_item do |f| %>
<% #category.items.each do |item| %>
<%= item.name %>
<%= f.hidden_field :item_id, value: item.id %>
<%= f.text_field :qty %>
<% end %>
<%= f.submit %>
<% end %>
<% end %>
<% end %>
So I am working through the Michael Hartl tut and this app works perfectly on the localhost but the moment I deploy to heroku it wont create a user when i submit the information. In fact it just sits there as if I just clicked on an empty screen, no error message nor a rediret. I looked at the heroku logs and there are no exceptions that I can see being logged. I tried updating the controller behavior but i get the same result. This is frustrating.
my form looks like this:
<div class="main-form">
<%= form_for(#user) do |f| %>
<%= render 'shared/error_messages'%>
<%= f.label :name %>
<%= f.text_field :name, class: "active" %><br/>
<%= f.label :email %>
<%= f.text_field :email %><br/>
<%= f.label :password %>
<%= f.password_field :password %><br/>
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %><br/>
</div>
<div class="actions">
<%= f.submit "create my account", class: "btn btn-lg btn-default" %>
</div>
<% end %>
my controller looks like:
class UsersController < ApplicationController
def new
end
def show
#user = User.find(params[:id])
#title = #user.name
end
def create
#title = "welcome"
#user = User.new(user_params)
if #user.password_confirmation.empty? == false
#user.save
redirect_to user_path(#user)
else
render 'new'
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
end
i have also tried setting up my create method like:
def create
#user = User.new(user_params)
if #user.save
redirect_to #user
else
render 'new'
end
end
neither of these methods worked? Any advice would be welcome.
If you inspect the page it looks like your submit button is outside of the form definition:
I am trying to add reCaptcha to my user create form. But I am running into some errors.
Error Im seeing in my logs
Nov 22 11:11:28 miningmonitor app/web.2: Recaptcha::RecaptchaError (Connection refused - connect(2))
Nov 22 11:11:28 miningmonitor app/web.2: app/controllers/users_controller.rb:27:in block in create
Nov 22 11:11:28 miningmonitor app/web.2: app/controllers/users_controller.rb:26:in create
Here is my Form Code
<%= form_for(#user) do |u| %>
<%= render 'shared/user_error_msg' %>
<%= u.label :name %>
<%= u.text_field :name %>
<%= u.label :email %>
<%= u.text_field :email %>
<%= u.label :coins, "Number of coins in your wallet(ex 4.5)" %>
<%= u.text_field :coins %>
<%= u.label :password %>
<%= u.password_field :password %>
<%= u.label :password_confirmation, "Confirmation" %>
<%= u.password_field :password_confirmation %>
<%= recaptcha_tags %>
<%= u.submit "Create my account", class: "btn btn-large btn-primary" %>
<% end %>
Now the user controller code for create
def create
#user= User.new(params[:user])
#user.name.strip!
respond_to do |format|
if(verify_recaptcha(:model => #user))
if #user.save
sign_in(#user)
format.html { redirect_to(#user, flash[:success] = "Welcome to Miners Canary!") }
else
format.html { render 'new' }
end
else
flash.delete(:recaptcha_error)
format.html { redirect_to(root_path, flash[:error] = "Please retry the reCaptcha Verification") }
end
end
end
In my config/initializers/recaptcha.rb
Recaptcha.configure do |config|
config.public_key = 'publickey'
config.private_key = 'privatekey'
config.use_ssl_by_default
config.proxy= 'https://miningmonitor.herokuapp.com:8080'
end
I am actually seeing the reCaptcha box on my screen. But when I try to sign up I get the errors above. in my config file I gave the url as my base url not the exact url to the sign up page. could that be a problem? Could also be setting up reCaptcha incorrectly. I was trying to follow this ambethia / recaptcha guide on github. I wish he had a few more examples.
Thanks for your help
I got my code working doing t the following steps my user controller looked like so
def create
#user= User.new(params[:user])
#user.name.strip!
if(verify_recaptcha(model: #user, message: "Error with reCaptcha!", private_key: ENV['RECAPTCHA_PRIVATE_KEY'], timeout: 10) && #user.save)
sign_in(#user)
flash[:success] = "Welcome to Miners Canary"
redirect_to #user
else
flash.delete(:recaptcha_error)
render 'new'
end
end
My user form looks like so
<%= form_for(#user) do |u| %>
<%= render 'shared/user_error_msg' %>
<%= u.label :name %>
<%= u.text_field :name %>
<%= u.label :email %>
<%= u.text_field :email %>
<%= u.label :password %>
<%= u.password_field :password %>
<%= u.label :password_confirmation, "Confirmation" %>
<%= u.password_field :password_confirmation %>
<%= recaptcha_tags display: { ssl: true, theme: 'clean' , tabindex: 1, public_key: ENV['RECAPTCHA_PUBLIC_KEY'] }%>
<%= u.submit "Create my account", class: "btn btn-large btn-primary" %>
<% end %>
Then to get it working with heroku I did these two commands
heroku config:set RECAPTCHA_PUBLIC_KEY = 'xxxxcxxxxxxxx'
heroku config:set RECAPTCHA_PRIVATE_KEY = 'xxxxcxxxxxxxx'
How can I make it so that my info only gets stored if the checkbox is checked. Here is what I have so far:
<% #extra.each do |extra| %>
<%= f.fields_for :purchaseds do |builder| %>
<div class="label-field">
<%= builder.label :name, extra.name %>
<p><%= extra.description %></p>
</div>
<div class="text-field">
$<%= extra.price %>
<%= builder.check_box :purchased %>
</div>
#I WOULD LIKE THIS TO ONLY GET SAVED IF THE CHECK BOX FOR PURCHASED IS CHECKED
<%= builder.hidden_field :name, :value => extra.name %>
<%= builder.hidden_field :description, :value => extra.description %>
<%= builder.hidden_field :price, :value => extra.price %>
<% end %>
<% end %>
My client asked to be able to add extra services himself, and then users could be able to choose if they want to purchase them as accessories to their order. So what I did was I made a table called Extra (for extra services) and another table called Purchased. Purchased belongs to Order and is a nested attribute.
In your purchaseds model add validations:
validates_presence_of :name, :description, :price, :if => :purchased
Update
Add :reject_if option to your purchaseds parent model in
accepts_nested_attributes_for :purchaseds, :reject_if => {|attrs| !attrs[:purchased]}