Radio Button with Multiple Values Rails - ruby-on-rails

I want to have multiple values saved when a radio button is selected. I tried to do this with a hidden_field but it did not work.
<%= form_for #checkin do |f| %>
<% #api["results"][0..9].each do |n| %>
<%= f.label :name, n["name"] %>
<%= f.radio_button(:name, n["name"]) %></br>
<%= f.hidden_field :placeid, :value => n["place_id"] %>
<%end%>
<%= f.submit %>
<%end%>
I am looping through a Google maps api json response and would like to save the name and place_id when a radio button is selected and submitted. Right now only the name saves correctly.
Here is the controller where I am creating a new Checkin with the checkin_params
class CheckinsController < ApplicationController
def index
#checkins = Checkin.all
end
def create
#checkin = Checkin.new(checkin_params)
if #checkin.save
redirect_to #checkin
else
render 'new'
end
end
def show
#checkin = Checkin.find(params[:id])
end
private
def checkin_params
params.require(:checkin).permit(:name, :placeid)
end
end
And here is the Searches Controller where I get the #api from
class SearchesController < ApplicationController
def new
#search = Search.new
end
def create
#search = Search.new(search_params)
#search.ip_address = "50.172.64.130"
if #search.save
redirect_to #search
else
render 'new'
end
end
def show
#search = Search.find(params[:id])
response = Search.get("https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=#{#search.latitude},#{#search.longitude}&keyword=#{#search.keyword}&types=&rankby=distance&key=AIzaSyAny_eoq9b1UGL7Ow20vDTet9yIBb60BwA")
#api = response.parsed_response
#checkin = Checkin.new
end
private
def search_params
params.require(:search).permit(:keyword)
end
end
Any tips on my existing idea or a suggestion for another way to accomplish this would be greatly appreciated!

Related

Adding records to a 'has_many :through' association using a button

This is my first Rails app and have hit another wall. I have a User model and a Country model. They have a many-to-many relationship, which I join together with a Trip model.
A user can maintain a list of countries that they have been to. On the Country page, I want to have a simple bootstrap button so the current_user can add or remove the country to their list.
I am using a partial that looks like the below to at least render buttons on all the pages.
_add_remove_countries.html.erb
<% if #user.countries.exists?(#country.id) %>
<%= form_for(#user) do |f| %>
<%= f.submit "Remove Country", class: "btn btn-info" %>
<% end %>
<% else %>
<%= form_for(#user) do |f| %>
<%= f.submit "Add Country", class: "btn btn-info" %>
<% end %>
<% end %>
I have tried a few different things, with no luck so I have just reverted to the basic structure. I am currently using a form_for, however that is just what has worked best so far, I am not tied to that solution.
Below are my controllers if needed, I have not set up a Trips controller as I am only using it to join the User and Country Model (maybe I need to set one up?).
users_controller.rb
class UsersController < ApplicationController
def index
#users = User.all
end
def show
#user = User.find(params[:id])
#countries = Country.all
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
session[:user_id] = #user.id
redirect_to #user
else
render 'new'
end
end
def update
redirect_to user_path
end
private
def user_params
params.require(:user).permit(:username, :email, :password, :password_confirmation)
end
end
countries_controller.rb
class CountriesController < ApplicationController
before_action :require_user, only: [:index, :show]
def index
#countries = Country.all
#sort = CS.countries.sort_by {|key, value| value}
#sort = #sort.first #sort.size - 2
end
def show
#country = Country.find(params[:id])
#user = User.find(session[:user_id])
end
end
my suggestion using collection_select (and click link in case you would like to know more about collection_select) to add countries to user while editing user, below is sample code to help (using edit method)
user_controller
class UsersController < ApplicationController
def index
#users = User.all
end
def show
#user = User.find(params[:id])
#countries = Country.all
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
session[:user_id] = #user.id
redirect_to #user
else
render 'new'
end
end
# ---> here additional code to edit method
def edit
#user = User.find(params[:id])
#countries = Country.all
end
def update
#user = User.find(params[:id])
if #user.update_attributes(user_params)
redirect_to user_path
else
render 'new'
end
end
private
def user_params
params.require(:user).permit(:username,
:email,
:password,
:password_confirmation,
:country_ids => [])
# country_ids is an array that will save data for countries that user have been to
end
end
now this is the fun one, in your views\user\edit.html.erb
<%= form_for #user do |f| %>
<!-- simple -->
<p>Email : </p>
<p><%= f.text_field :email %></p>
<!-- if you using bootstrap -->
<div class="row form-group">
<%= f.label "email", :class => 'control-label col-sm-3' %>
<div class="col-sm-5">
<%= f.text_field :email, :class => 'form-control' %>
</div>
</div>
<!-- other inputs (password / password_confirmation) -->
<%= f.collection_select :country_ids, #countries, :id, :name, {}, { multiple: true, class: 'form-control' } %>
<% end %>

No route matches while creating nested resource in Rails

I am trying to create a new teacher for a specific school in my project and I got this error:
No route matches [POST] "/schools/3/teachers/new"
Here is my teachers_controller.rb:
class TeachersController < ApplicationController
def new
#teacher = Teacher.new
end
def create
#teacher = Teacher.new(teacher_params)
#teacher.save
redirect_to school_path(school)
end
private
def teacher_params
params.require(:teacher).permit(:firstName, :lastName, :middleName)
end
end
schools_controller.rb:
class SchoolsController < ApplicationController
def show
#school = School.find(params[:id])
end
def new
#school = School.new
end
def edit
#school = School.find(params[:id])
end
def update
#school = School.find(params[:id])
if #school.update(school_params)
redirect_to #school
else
render 'edit'
end
end
def index
#schools = School.all
end
def create
#school = School.new(school_params)
if #school.save
redirect_to schools_path
else
render 'new'
end
end
def destroy
#school = School.find(params[:id])
#school.destroy
redirect_to schools_path
end
private
def school_params
params.require(:school).permit(:name)
end
end
routes.rb:
Rails.application.routes.draw do
resources :schools do
resources :teachers
end
# The priority is based upon order of creation: first created -> highest priority.
# See how all your routes lay out with "rake routes".
# You can have the root of your site routed with "root"
root 'welcome#index'
And teachers/new.html.erb:
<%= form_for :teacher, url: school_teachers_path(school) do |f| %>
<p>
<%= f.label :firstName %><br>
<%= f.text_field :firstName %>
</p>
<p>
<%= f.label :lastName %><br>
<%= f.text_field :lastName %>
</p>
<p>
<%= f.label :middleName %><br>
<%= f.text_field :middleName %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
As your teacher resource is nested under the school resource, so you need to pass the school when you try to create a teacher.
Try changing your new and create actions in teachers_controller.rb to something like this:
def new
#school = School.find(params[:school_id])
#teacher = #school.teachers.build
end
def create
#school = School.find(params[:school_id])
#teacher = #school.teachers.build(params[:teacher])
#teacher.save
redirect_to school_path(#school)
end
And, then change your form to this:
<%= form_for([#school, #teacher]) do %>
. . .
. . .
<% end %>
Try this in your form:
<%= form_for [school, Teacher.new] do |f| %>
The path you are posting to is for the index of teachers at a school:
school_teachers GET /schools/:school_id/teachers(.:format) teachers#index
I believe that it's a has_many belongs_to association. So you need to first change your teacher controller create action and new action.
class TeachersController < ApplicationController
def new
get_school
#teacher = #school.teachers.build
end
def create
get_school
#teacher = #school.teachers.build(teacher_params)
If #teacher.save
redirect_to school_path(school)
else
render 'new'
end
private
def teacher_params
params.require(:teacher).permit(:firstName, :lastName, :middleName)
end
def get_school
#school = School.find (params [:school_id])
end
end
Then in your form you 'll do :
<%= form_for([#school,#teacher]) do |f| %>
Hope this will help

How can i update the value of my rails model from the show page?

In my rails app I'm making a guess at the user's gender based on some information that the user enters on the 'new' form. After that the user is taken to the show page, where I reveal the guess. I want the user to tell me if I was right or wrong so i can improve the data. I want to have 'yes' and 'no' buttons where
'no' updates the user's record in the db with the other gender.
Here's my show view
<div class='container'>
<header>We think you're.....</header>
<div class='cmn-t-shake'>
<%= #person.male ? "Male" : "Female"%>
</div>
<div>
Were we right? <br/>
<%= link_to 'Yes', '/people'%>
|
<%= link_to 'No', 'people/flip_gender(#person)'%>
</div>
<div>
<%= link_to 'Learn more', '/people'%>
</div>
</div>
and a snippet of my controller
class PeopleController < ApplicationController
def index
#men = Person.where("male = ?", true)
#women = Person.where("male = ?", false)
end
def new
#person = Person.new
end
def show
#person = Person.find(params[:id])
end
def create
#person = Person.new(person_params)
#person.male = guessGender(#person)
if #person.save
path = '/people/' + #person.id.to_s
redirect_to path
else
render 'new'
end
end
def person_params
params.require(:person).permit(:male, :height_in_inches, :weight_in_lbs)
end
def flip_gender(p)
p = Person.find(params[:id])
person.gender = !p.flip_gender
p.save
end
and my routes.rb
root 'people#new'
get 'people' => 'people#index'
get 'people/new' => 'people#new'
post 'people' => 'people#create'
get 'people/:id' => 'people#show'
How can I user flipGender to update and save the current record on the show page at the click of a button/link?
You could make flipGender a helper method which should make it accessible from the view:
def flip_gender(p)
p = Person.find(params[:id])
person.gender = !p.flip_gender
p.save
end
helper_method: flipGender
and then in your view:
<% flipGender(p) %>
or something like that. You could also create a file for helper methods, and then include it in the ApplicationController so those methods will be available check out this thread

my rails dropdown form generates nil no matter what is selected how do i fix it?

I am new at RoR, I have been searching and searching but can't seem to find a solution. I have a simple form:
<%= form_for #case do |f| %>
<%= f.select( :case, options_for_select([['CASE1','CASE1'],['CASE2','CASE2'],['CASE3','CASE3'],['CASE4','CASE4']])) %>
<% end %>
That is in my nav bar. It is not based on any table in the DB.
Controller:
class MyAppController < ApplicationController
before_filter :initialize_remote_user
def self.search(name)
#results = MyApp.search(params[:name])
#case = params[:case]
end
def result
#results = MyApp.where("name = ?",params[:name]).order("item_scan_date ASC")
puts #results.inspect
end
def update
end
def change
end
def show
#case = params[:case].inspect
end
def create
end
def new
end
def index
end
private
def name_params
params.require(:name).permit(:name)
end
def case_params
params.require(:case).permit(:case, :id)
end
When I have #case = params[:case].inspect it doesn't have any errors, but it doesn't pull the data from the <%= form_for #case do |f| %>
I have tried
def show
#case = Case.find(params[:case])
end
but end up with NameError uninitialized constant MyAppController::Case error at #case = Case.find(params[:case])
I can't seem to get #case to pull up anything but nil
If I have #case = params[:case] in def show I get 'ArgumentError First argument in form cannot contain nil or be empty error at <%= form_for #case do |f| %>
Try simple_form for your forms see: https://github.com/plataformatec/simple_form and read the documentation under Collections to handle input for :case
Also make sure your create and new methods aren't empty, or else your form won't save.
Hope it helps.

Submit Form and Create action for a Polymorphic Association

I received help Setting up a polymorphic association
I am now having trouble implementing the submit form and create action. A user just needs to follow and unfollow each model.
In my Follow Controller
class FollowsController < ApplicationController
before_filter :find_supports
def create
#relation = find_supports
#follow = #relation.find(params[:follow])
current_user.follows.follow!(#follow)
respond_to do |format|
format.html { redirect_to :back }
format.js
end
end
def destroy
#follows = Follow.find(params[:id]).followable
current_user.unfollow!(#follows)
respond_to do |format|
format.html { redirect_to :back }
format.js
end
end
private
def find_supports
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
else
nil
end
end
end
end
In my Follow Form, which is rendered at on my polymorphic models
EDIT
<%= form_for #cause.follows.build(params[:follow]) do |f| %>
<div><%= f.hidden_field :followable_id %></div>
<div><%= f.hidden_field :followable_type %></div>
<div><%= f.hidden_field :follower_id %></div>
<div class="create-button"><%= f.submit "Follow" %></div>
<% end %> <!-- I now get the values for followable_id and followable_type, but it
wont get grab the follower_id and I get an error in the create action -->
and in my User Model, I have these 3 methods
def following?(follow)
follows.find_by_followable_id(follow)
end
def follow!(followable)
follows.create![] ##I have tried many different params here
end
def unfollow!(followable)
follows.destroy(params[:followable_id]).destroy
end
I cannot get the follower_id, followable_id and followable_type to save properly. Any suggestions?
Thanks in advance, I have spent many hours with this.
Here is how I solved my issues. The answer is using AJAX and Devise helper method current_user
Form Partial
<%= form_for #relation.supports.build(params[:support]), :remote => true do |f| %>
<div><%= f.hidden_field :supporter_id, :value => current_user.id %></div>
<div><%= f.hidden_field :supportable_id %></div>
<div><%= f.hidden_field :supportable_type %></div>
<%= f.submit "Support", :class => "support-button" %>
<% end %>
My Controller
class SupportsController < ApplicationController
before_filter :find_relation
def create
#relation.supports.create!(params[:support])
respond_to do |format|
format.html { redirect_to :back }
format.js
end
end
def destroy
#relation.supports.find(params[:id]).destroy
respond_to do |format|
format.html { redirect_to :back }
format.js
end
end
private
def find_supports(instance_params)
class_name = instance_params["supportable_type"].classify.constantize
class_name.find(instance_params["supportable_id"])
end
def find_relation
#relation = find_supports(params[:support])
end
end
Also, add a before_filter in all the controllers that render the form to find the correct object. This will allow you use the same form partial with all your polymorphic classes.
def find_supports
#relation = YourClass.find(params[:id])
end

Resources