Rails create two objects from one form - ruby-on-rails

I have two models with a has_one relationship between them. The Event class which "has_one" Location. What I am trying to achieve is in the form where I create an event, I have a "Where?" field which is populated asynchronously through the Foursquare API.
Since I could not possibly migrate the whole of the Foursquare API to my own database, I want to generate a Location entry in my database the first time a location is mentioned in an event.
At the moment the result I am looking for is completed, but I think I am using to many hidden fields and a lot of javascript assignments. Is there a better practice than the one I am using to achieve the same result?
new.html.erb
<%= form_for :event, :url=> new_event_path, :method => :get, :remote => :true, :html => {:class => 'form-horizontal'} do |f| %>
<%= fields_for :location do |f1|%>
<%= f1.hidden_field :lat, :id=> 'foursquare-latitude' %>
<%= f1.hidden_field :lng, :id => 'foursquare-longitude' %>
<%= f1.hidden_field :foursquare_id, :id =>'foursquare-id' %>
<%= f1.hidden_field :name, :id =>'location-name-field' %>
<% end %>
<!-- TODO Encapsulate in location model -->
<%= f.hidden_field :latitude, :id=>'latitude-field' %>
<%= f.hidden_field :longitude, :id=>'longitude-field' %>
<div class="control-group">
<%= f.label :title , :class => "control-label" %>
<div class="controls">
<%= f.text_field :title %>
</div>
</div>
<div class="control-group">
<label class="control-label" for="location">Where?</label>
<div class="controls">
<input type="text" id="location" data-provide="typeahead">
<br/>
<img src="../img/fsq.png" alt="Powered By Foursquare" width="240px" />
</div>
</div>
<div class="control-group">
<%= f.label :body, :class => "control-label" %>
<div class="controls">
<%= f.text_area :body, :rows => 6 %>
</div>
</div>
<div class="control-group">
<div class="controls">
<%= f.submit %>
</div>
</div>
<% end %>
events controller
def new
#location = Location.new(params[:location])
if #location.save
#event = Event.new(params[:event])
#event.author = current_user
#event.location_id = #location.id
respond_to do |format|
if #event.save
format.js {render :action => "new"}
else
format.js {render :action => "new"}
end
end
end
end

Related

Type error on nested form

been banging my head on the table over this one. I have another nested form but this one is driving me crazy.
The error is:
TypeError in CompaniesController#create
no implicit conversion of Symbol into Integer
#company = Company.new(company_params)
The controller:
class CompaniesController < ApplicationController
layout 'welcome'
def new
#company = Company.new
end
def create
#company = Company.new(company_params)
if #company.save
flash[:notice] = "New company created successful."
redirect_to admin_accounts_path
else
flash.now[:alert] = "Creation failed, please try again"
render :new
end
end
private
def company_params
params.require(:company).permit(:name, :location, :users_attributes => [:email, :password])
end
end
On the new.html.erb:
<%= render partial: 'form', locals: { company: #company, users_attributes: :users_attributes } %>
This code looks exactly like another nested setup I have, but it works :p
I had read that sometimes changing the params from => to just having a semicolon works, but replacing the user_attributes => with a user_attributes: didn't change anything.
EDIT: form.html.erb
<%= form_for company, url: companies_path do |f| %>
<div class="col-12">
<div class="row">
<div class="col p-0 mr-3">
<div class="form-group">
Company <%= f.label :name %>
<%= f.text_field :name, :placeholder => 'Company name', class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :location %>
<%= f.text_field :location, :placeholder => 'Location', class: 'form-control' %>
</div>
</div>
<div class="col p-0">
<%= f.fields_for users_attributes do |user_f| %>
<div class="form-group">
<%= user_f.label :email %>
<%= user_f.text_field :email, :placeholder => 'Your Email Address', class: 'form-control' %>
</div>
<div class="form-group">
<%= user_f.label :password %>
<%= user_f.password_field :password, :placeholder => 'Password', class: 'form-control' %>
</div>
<% end %>
</div>
<div class="col-12 p-0">
<%= f.submit "Sign-Up", :class => 'btn btn-primary btn-block btn-lg' %>
</div>
</div>
</div>
<% end %>
Use users instead of users_attributes on the form.
Don't forget to define accepts_nested_attributes_for :users in model Company
## new.html.erb
<%= render partial: 'form', locals: { company: #company, users_attributes: :users } %>
I wonder why you didn't put :users into the form directly

Ruby on Rails: Keep check boxes selected after search

In my RoR application I have a form whereby users can search for their contacts by first name and select the ones that they want to send an email to. My problem is that after searching for say "Tom", and selecting the checkbox for "Tom", if they then reset the search to display all check boxes "Tom" is no longer selected.
Can someone please tell me how this can be sorted?
The code in the view is:
<div class="panel-body">
<%= form_tag '/emails/contact_search', :method => 'get' do %>
<p>
<%= text_field_tag :search_string, params[:search_string], :placeholder => "Search by firstname" %>
<%= submit_tag "Search" %>
</p>
<% end %>
<%= form_for(#email) do |f| %>
<fieldset>
<div class="form-group">
<label>From Email Address</label></br>
<% #useraccounts.each do |useraccount| %>
<%= f.radio_button :account_id, useraccount.account_id, :checked => false %>
<%= f.label :account_id, useraccount.account.email, :value => "true" %><br>
<% end %>
</div>
<div class="form-group">
<label>Contacts</label></br>
<%= f.collection_check_boxes :contact_ids, #contacts, :id, :fullname, checked: #selected_contact_ids %>
</div>
<div class="form-group">
<label>Groups</label></br>
<%= f.collection_check_boxes :group_ids, Group.where(user_id: session[:user_id]), :id, :name ,{ prompt: "name" } %>
</div>
<div class="form-group">
<label>Attachment</label>
<%= f.file_field :attachment, :size => 42 %><br>
</div>
<div class="actions">
<%= f.submit "Continue", {:class => 'btn btn-primary '} %>
<%= render "/error_messages", :message_header => "Cannot save: ", :target => #email %>
</div></br>
</fieldset>
<% end %>
</div>
The controller code for the search is:
def contact_search
#email = Email.new(session[:email_params])
#email.current_step == session[:email_step]
#useraccounts = Useraccount.where(user_id: session[:user_id])
#contacts = Contact.contact_search(params[:search_string])
if #contacts.empty?
flash[:notice] = "There are no emails with that subject"
#contacts = Contact.all
end
render :action => "new"
end
private
def email_params
params.require(:email).permit(:subject, :message, :account_id, { contact_ids: [] }, { group_ids: [] }, :attachment)
end
And in the model:
def self.contact_search(search_string)
self.where("firstname LIKE ?", search_string)
end
I cannot work out how to keep a checkbox selected after a user then searches for something else or resets the search, can someone please shed some light on how this can be achieved?
This seems to be one of those obscure and badly documented features of Rails. What has to be done is pass an array if ids to be checked into the checked parameter
= f.collection_check_boxes :contact_ids, #contacts, :id, :fullname, checked: #selected_contact_ids
and then check boxes with items of id 1, 2 and 3 will be checked. You will need to pass this array obviously from the controller somehow. E.g.
#selected_contact_ids = email_params.fetch(:contact_ids, [])

How to implement upload photo feature in rails?

My repo: https://github.com/Gtar69/artstore_hw2
I want to implement upload more than 1 photo in certain product.
The basic idea is that administrator enter edit page of the product and can "upload new photos" for certain product.Im struggling in "how to create a photo object in edit page and add this photo object to product. !!! I can not successfully create a photo object in edit page .....
Very Thanks
in view/admin/products/edit.html.erb
<h2> 編輯 <%= #product.title %> </h2>
<%= simple_form_for [:admin, #product ] , :html => { :class => "form form-horizontal" } do |f| %>
<div class="form-group">
<div class="col-sm-10">
<%= f.input :title %>
</div>
</div>
<div class="form-group">
<div class="col-sm-10">
<%= f.input :description, :as => :text %>
</div>
</div>
<div class="form-group">
<div class="col-sm-1">
<%= f.input :quantity %>
</div>
</div>
<div class="form-group">
<div class="col-sm-1">
<%= f.input :price %>
</div>
</div>
<!-- 20140623 upload more than one photo feature added -->
<div>
<%= simple_form_for [:admin, #product, #product.photos.build] do |f| %>
<%= f.input :image , :as => :file %>
<div class="form-group">
<%= f.submit "upload new photos", :class => "btn btn-default" , :disable_with => 'Submiting...' %>
</div>
<%end%>
</div>
<div class="form-group">
<%= f.submit "Submit", :class => "btn btn-default" , :disable_with => 'Submiting...' %>
</div>
<% end %>
in controllers/admin/products_controller.rb
def edit
#product = Product.find(params[:id])
##photo = #product.photos.build
##product.add_photo_to_product(#photo)
end
in controllers/admin/photos_controller.rb
def create
#binding.pry
#product = Product.find(params[:product_id])
#photo = #product.photos.create(photo_params)
#product.add_photo_to_product(#photo)
redirect_to admin_products_path
end
private
def photo_params
params.require(:photo).permit(:image)
end
in model/product.rb
class Product < ActiveRecord::Base
has_many :photos
accepts_nested_attributes_for :photos
validates :title , :presence => true
validates :quantity , :presence => true
def default_photo
photos.first
end
def add_photo_to_product(photo)
photos << photo
end
end
in photos.rb
class Photo < ActiveRecord::Base
belongs_to :product
mount_uploader :image, ImageUploader
end

Rails 4 - associations between controllers, id not getting passed

I have two controllers categories and products. Products belongs to categories but I'm having trouble setting up the relationship.
In category.rb
has_many :products
In product.rb
belongs_to :category
validates :category_id, :presence => true
validates :name, :presence => true, :uniqueness => true
When I try to create a new product, the record does not save because category_id is blank. My product form looks like so:
<%= form_for #product, :html => { :class => 'form-horizontal' } do |f| %>
<%= f.hidden_field('category_id', :value => params[:category_id]) %>
<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 :category, :class => 'control-label' %>
<div class="controls">
<% #cat = Category.all %>
<%= select_tag 'category', options_from_collection_for_select(#cat, 'id', 'name') %>
</div>
</div>
<div class="control-group">
<%= f.label :price, :class => 'control-label' %>
<div class="controls">
<%= f.text_field :price, :class => 'text_field' %>
</div>
</div>
<div class="control-group">
<%= f.label :description, :class => 'control-label' %>
<div class="controls">
<%= f.text_area :description, :class => "tinymce", :rows => 10, :cols => 120 %>
<%= tinymce %>
</div>
</div>
<div class="form-actions">
<%= f.submit nil, :class => 'btn btn-primary' %>
<%= link_to t('.cancel', :default => t("helpers.links.cancel")),
products_path, :class => 'btn' %>
</div>
<% end %>
and in the products controller I have:
def new
#product = Product.new
#category = #product.category
end
I've tried looking through other questions on SO but haven't had any luck finding the correct way to pass the category id to products.
I hope I've been clear enough and I'm happy to provide any extra information that may be needed.
EDIT
I've made the following changes to the products controller as suggested by I not get the error: Cannot find Category without an ID
before_filter :set_category, only: [:create]
def set_category
#category = Category.find(params[:category_id])
end
def create
#product = #category.products.new(product_params)
#....
end
I'm using nested routes like so:
resources :categories do
resources :products
end
You should set product's category in create action:
def create
#product = #category.products.new(product_params)
# ...
end
in new action, you should just have
def create
#product = Product.new
end
Of course, you need to set #category (#category = Category.find(params[:category_id])) instance variable before (in before_filter, for example).
You should also remove this hidden field from view and remove category_id from allowed params if you don't want users to set category_id manually and set form_for arguments properly, since you're using nested resources:
form_for [#category, #product]

Ruby On Rails Form with integers titles instead of numbers in a drop-select-list

Hi
I'm pretty new with Ruby On Rails, and came across this problem.
I have 4 tables, and 1 that has the three others connected to it.
Sportcategories - name of each category
Sports - Name of each sport
Clubs - Name of each club
Results,
t.integer "sportcategory_id"
t.integer "sport_id"
t.integer "club_id"
I have managed to make a simple edit form with text_field for each field in results. But how can I get the names for the integers instead of the numbers?
<%= form_for(#result) do |f| %>
#if...
#..
#end
<div class="field">
<%= f.label :sportcategory_id%><br />
<%= f.text_field :sportcategory_id%>
</div>
<div class="field">
<%= f.label :sport_id %><br />
<%= f.text_field :sport_id %>
</div>
<div class="field">
<%= f.label :club_id %><br />
<%= f.text_field :club_id %>
</div>
<div class="field">
<%= f.label :result %><br />
<%= f.text_field :result %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I have made it so that SportCat, Sports and clubs has many results and that results belongs to all of them.
This is my controller file for results with edit & update
def edit
#result = Price.find(params[:id])
end
def update
#price = Price.find(params[:id])
respond_to do |format|
if #price.update_attributes(params[:price])
format.html { redirect_to(#price, :notice => 'Price was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #price.errors, :status => :unprocessable_entity }
end
end
end
And question two might be answered in question one, but I want to be able to choose from a drop-down list from all the available categories, sports and clubs with their actual name and then pass the right ID when I update it.
Check the Rails Form select helper
http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-select
<%= form_for(#result) do |f| %>
<div class="field">
<%= f.label :sportcategory_id%><br />
<%= f.select :sportcategory_id, #sportcategories.map {|s| [s.name, s.id]} %>
</div>
<div class="field">
<%= f.label :sport_id %><br />
<%= f.select :sport_id, #sports.map {|s| [s.name, s.id]} %>
</div>
<div class="field">
<%= f.label :club_id %><br />
<%= f.select :club_id, #clubs.map {|c| [c.name, c.id]} %>
</div>
<div class="field">
<%= f.label :result %><br />
<%= f.text_field :result %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Get #sportcategories, #sports, #clubs in your controller actions.

Resources