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
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 %>
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
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
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.
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