Ruby on rails adding users to groups - ruby-on-rails

I am building a social networking site with user, school, and schoolgroup models. The users join, and have different roles in, the schools through the has_many through schoolgroups. I am having trouble writing an online form_for button that a user can click on to apply to the school. The params I need to be included in the creation of the schoolgroup object are the user_id, the school_id, and the role 'applicant'. I know that I can use current_user.schoolgroups.build to have the form initialize a create action and include the correct user_id, but the problem I am having is how to write a form which sends the school_id to the controller to create the new schoolgroup object. The #school instance variables in my code are just placeholders for whatever the correct code should be
def create
#school = School.find(params[:schoolgroups][:school_id)
current_user.schoolgroups.build(school_id: #school.id, user_id: current_user.id, role: 'applicant')
respond_with school_path
end
<%= form_for( current_user.schoolgroups.build(params[school_id: #school.id]),
remote: true) do |f| %>
<div><%= f.hidden_field :school_id %></div>
<%= f.submit "Apply", class: "btn btn-large btn-primary" %>
<% end %>

I'd go this way
# in routes
resources :schools do
member do
put :apply
end
end
# in schools_controller.rb
def apply
#school = School.find(params[:id])
#schoolgroup = current_user.schoolgroups.create(school: #school, role: 'applicant')
respond_with #schoolgroup
end
#in your view
<%= link_to "Apply", apply_school_path(#the_school_var_you_define_somewhere), remote: true, method: :put,
class: "btn btn-large btn-primary" %>
This is simplier, and more in the Rails spirit.

Related

Redirecting to "show" view of a model object when searched by attributes (NOT id)

I have a form where users look for a particular bill by some attributes of that bill, namely the "Congress Number", "Bill Type", and "Bill Number", as in 114-H.R.-67 . I want to "show" the appropriate bill, but to do that I have get the appropriate bill model in a separate action which I've called "find_by_attributes". Inside this action I perform:
#bill = Bill.find_by( params ).first
which correctly acquires the appropriate bill's id.
Now I simply want to redirect to the "show" method of this bill, as in the url
".../bills/[#bill.id]"
As of right now, at the end of my "find_by_attributes" action I do
redirect_to bills_path(#bill)
which correctly loads the show.html.erb with #bill, but does not change the url (the url is still shows the "find_by_attributes" action followed by a long query-string, instead of the clean "/bills/[:bill_id]".
How can I restructure my code to achieve the neat redirect that I desire?
Full code below:
THE FORM
<%= form_tag("bills/find_or_create", :method => :get ) do |f| %>
<%# render 'shared/error_messages', object: f.object %>
<%= fields_for :bill do |ff| %>
<%= ff.label :congress, 'Congress (i.e. 114)' %>
<%= ff.number_field :congress, class: 'form-control' %>
<%= ff.select :bill_type, options_for_select(
[['House of Representatives', 'hr'],
['Senate', 's'],
['House Joint Resolution', 'hjres'],
['Senate Joint Resolution', 'sjres'],
['House Concurrent Resolution', 'hconres'],
['Senate Concurrent Resolution', 'sconres'],
['House Resolution', 'hres'],
['Senate Resolution', 'sres']]
)
%>
<%= ff.label :bill_number, 'Bill number (i.e. 67)' %>
<%= ff.number_field :bill_number, class: 'form-control' %>
<% end %>
<%= submit_tag "Submit", class: "btn btn-primary" %>
<% end %>
THE CONTROLLER ACTIONS
def find_by_attributes
#bill = Bill.where(bill_params).first_or_create(bill_attributes)
redirect_to bills_path(#bill)
end
def show
puts bill_params
if params[:bill]
#bill = Bill.where(bill_params).first_or_create do |bill|
bill.attributes = bill_attributes
end
else
#bill = Bill.find(params[:id])
end
#subjects = Subject.where("bill_id = ?", #bill[:id])
#bill_comments = Comment.where("target = ?", #bill[:id])
end
ROUTES FILE
...
resources :bills do
get :find_by_attributes
end
...
EDIT
I make use of the turbolinks gem in my rails application.
the thing I see here is that you are calling to
redirect_to bills_path(#bill)
that in theory is not the show path, you just need to remove the "s"
redirect_to bill_path(#bill)
and as a side comment, in this line, you don't need the first part, because find_b, finds the first record matching the specified conditions, you can remove that part.
#bill = Bill.find_by( params )

custom action submitting multiple forms in Rails

So I have this structure of application: a Game model which has many Allies and many Enemies.
I want to create a custom action for Game dedicated to create and submit enemies and allies.
So in the view I will have 2 fields_for that you can submit at the same time.
I have never created custom routes and actions or submitted 2 children forms in the same page.
Anyone know how I could do this ? Thanks
routes.rb
#this route shows the form
get 'create-players/:id', to 'game#new_players', as: :new_players
# this route recieves the form post submission
post 'create-players/:id', to 'game#create_players', as: :create_players
app/controllers/game_controller.rb:
def new_players
#game = Game.find(params[:id])
end
def create_players
#do whatever you want with the params passed from the form like
#allies = Ally.create(game_id: params[:id], name: params[:ally_fields][:name])
#enemies = Enemy.create(game_id: params[:id], name: params[:enemy_fields][:name])
#game = Game.find(params[:id])
end
app/views/game/new_players.html.erb:
<%= form_tag(create_players_paths, #game.id), method: 'POST') do %>
<% #...fields you have on models, perhaps %>
<% fields_for :ally_fields do |f|
<%= f.text_field :name, nil, placeholder: "Ally name", required: true
<% end % >
<% fields_for :enemy_fields do |f|
<%= f.text_field :name, nil, placeholder: "Enemy name", required: true
<% end % >
<%= submit_tag "create players", class: "submit" %>
<% end %>
app/views/game/create_players.html.erb:
<h1> Woah an allie and an enemy have been added to game <%= #game.id %></h1>
<p> Lets see some blood!</p>
Of course, you should enforce verifications on the input and before processing the post submission. Usually you'll want to use established relationships between objects, so that you can do on the view #model = Modelname.new then, form_for #object and have validations and error messages accessible in a much cleaner way.

Ror find record in db and show it to user

This is my first ror app.
I have main page: home.html.erb
I have form there.
<%= form_for(#lead ,:html => {:class => 'check_form'}) do |f| %>
<%= f.text_field :phone, placeholder: 'phone' %>
<%= f.submit "Check car status", class: "btn btn-large btn-primary" %>
<% end %>
Backstory: a customer(I call him Lead can input his phone number and check status of his car which is being repaired now.)
Right now this view home.html.erbis served by static_pages_controller
class StaticPagesController < ApplicationController
def home
#lead = Lead.new()
end
def help
end
def about
end
def contact
end
end
I have also LeadsController
class LeadsController < ApplicationController
*some code*
def create
#lead = Lead.new(lead_params)
if #lead.save
#sign_in #lead
flash[:success] = "Request successfully created!"
redirect_to #lead
else
render 'new'
end
end
* some code
end
What I want to do when user inputs his phone number to find lead in database with the same phone number and show repair status to user.
So back to my problem:
I know how to find lead by phone like this Lead.find(params[:id])
But where to write this code? I need to find lead by phone and then print it to screen. How can I do this?
What I want to do when user inputs his phone number to find lead in
database with the same phone number and show repair status to user.
Currently your form serves the wrong purpose. This requires a form with GET request. I'll be doing it by declaring a custom route like below
get :check_lead_car_status, to: 'static_pages#check_lead_car_status', as: 'check_lead_car_status'
And in the static_pages#check_lead_car_status
def check_lead_car_status
#lead = Lead.find_by(phone: params[:phone]
end
And modify the existing form like below
<%= form_tag check_lead_car_status_path, :method => :get do %>
<%= text_field_tag :phone, placeholder: 'phone' %>
<%= submit_tag "Check car status", class: "btn btn-large btn-primary" %>
<% end %>
And a page check_lead_car_status.html.erb with the below code
The Status of the Car is: <%= #lead.status %>
youre redirecting to #lead which means should be the show path in the lead controller. which means you need to put that logic in a method called show in your Lead controller
then in your view (views/leads/show.html.erb) you can access that variable
edit:
if all youre trying to do is query by a different parameter, then you should look into the active record query interface. specifically section 1.1.5
Lead.find_by(phone: params[:phone])

Updating a rails attribute through a model association

I have two models shop and user. Shop has_many Users and User has_one Shop. I'm trying to create a button on shop/show that allows a user to choose its shop. The button should send the parameter shop_id to Users_Controller#update_shop which then changes User.shop_id to the id of the shop on the page.
The current method in Users_Controller#update_shop is the following:
def update_shop
#user = User.find(params[:id])
#user.update_attributes(shop_id: params[:shop][:id])
flash[:success] = "Added Shop!"
end
And the button on show/shop is this:
<%= form_for User.update_shop, remote: true do |f| %>
<%= f.hidden_field :shop_id, value: #shop.id %>
<%= f.submit 'Add As Your Shop', :class => 'button blue-button' %>
<% end %>
I'm getting the error NoMethodError in ShopsController#show undefined methodupdate_shop' for #`. The method is defined in the Users controller though.
I understand there is probably a more efficient way to update User.shop_id through the association, so tips on doing that or getting this to work are greatly appreciated.
I think it's better to have a link with POST method in place of form:
<%= link_to 'Add As Your Shop', update_shop_url(id: #user.id, shop_id: #shop.id, class: 'button blue-button', data: { method: 'post' } %>
With this setup you should change controller method as well:
def update_shop
...
#user.update_attributes(shop_id: params[:shop_id])
...
end

Getting a Controller, Route and Hidden-Field-Button to work correctly in Rails

I would like to create a button so that a user can enroll in a course. The enrolling model belongs_to users and courses and should keep track of enrollment.
I have the following code displayed as a button-form on a course page (looks fine):
<% #enroll = current_user.enrollings.build(course_id: #course.id) %>
<%= form_for(#enroll) do |f| %>
<div><%= f.hidden_field :course_id %></div>
<%= f.submit "Enroll", class: "btn btn-large btn-primary" %>
<% end %>
I have a resources route for enrollings, and when the user clicks on the button, the page goes to /enrollings.
This is the code in the enrolling controller:
def create
#course = Course.find(params[:course_id])
current_user.enroll!(#course)
end
When I click on the button, I get the following error message:
ActiveRecord::RecordNotFound in EnrollingsController#create
Couldn't find Course without an ID
Why isn't it passing the course_id with the form? How do I setup the controller correctly?
Try this instead:
<div><%= hidden_field_tag "course_id", #course.id %></div>

Resources