I have a link that looks like this in the object's show view:
<%= link_to "Approve", object_path(#object, status: true), method: :put, confirm: "Are you sure?", class: 'button' %>
The update action in the controller is standard and the object's regular edit form works just fine. But for some reason, this link isn't updating the boolean field to true...
Is there something that I did wrong with this link?
EDIT: Update Section of Controller
def update
#object = Object.find_by_certain_field(params[:id])
if #object.update_attributes(params[:object])
flash[:success] = "Object Updated"
redirect_to #object
else
render 'edit'
end
end
object_path(#object, status: true) causes params[:status] to be true and not params[:object][:status] as you wish, thus not updating the object with #object.update_attributes(params[:object])
If you want to keep using the current code pattern just add
parmas[:object] ||= {}
params[:object][:status] = params[:status] if params[:status]
before
if #object.update_attributes(params[:object])
and everything should be fine.
Otherwise I'd avise you to make a form for this update call:
<% form_for #object, :method => :put do |f| %>
<%= f.hidden_field :status, :value => true %>
<%= f.submit "Approve" %>
<% end %>
Related
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 )
I have a modal that will serve as a disclaimer in my app and I need the link at the bottom of the modal that says "agree & continue" to toggle a boolean and input the time that the boolean was toggled. I have created the button as a form with hidden links but I cant seem to see how to make it submit the form AND redirect to the path i specify. Here is my link_to code now.
<% if current_user.user_record.blank? %>
<%= form_for :user do |f| %>
<% f.hidden_field :disclosure_acceptance, :value => true %>
<% f.hidden_field :disclosure_date, :value => Time.now %>
<%= link_to("Agree & Continue", user_steps_path(current_user), class: "btn btn-primary") %>
<% end %>
<% end %>
First, create a new method in your user_records_controller or at whichever controller action the form is displayed at:
def new
#user_record = current_user.build_user_record
end
Put this in your view:
<% if current_user.user_record.blank? %>
<%= form_for #user_record do |f| %>
<%= f.hidden_field :disclosure_acceptance, :value => true %>
<%= f.hidden_field :disclosure_date, :value => Time.now %>
<%=f.submit "Agree & Continue", class: "btn btn-primary") %>
<% end %>
<% end %>
Make a create action for the user_record that looks like this:
def create
#user_record = current_user.build_user_record(permitted_params)
if #user_record.save
redirect_to user_steps_path(current_user)
else
render :new
end
end
private
def permitted_params
params.require(:user_record).permit(:disclosure_acceptance , :disclosure_date) #etc
end
UPDATE
If you directly want to jump to the 'create' action, you can make your configuration like this:
Add a custom action to your routes:
post 'rate/:article_id' => 'user_records#create' :as => :create_user_record
#or whichever controller/action you wish
You should update the route on your form:
= form_tag create_user_record_path, :method=>'post' do
#etc
In order to create a user_record from the controller, you need to change things a little bit:
def create
current_user.user_record.create(:user_id => current_user.id, :disclosure_acceptance => params[:disclosure_acceptance] , :disclosure_date => params[:disclosure_date])
if current_user.user_record.save
#etc
end
In my User Show view:
<%= form_tag assign_as_student_path do %>
<%= hidden_field_tag :user_id, #user.id %>
<%= submit_tag "Assign as a Student", data: { confirm: "Are you sure?" } %>
<% end %>
TeachersController (inherits from UsersController):
def assign_as_student
#user = User.find(params[:user_id])
#user.update_attributes(type: "Student")
#user.save
redirect_to admin_path, notice: "They are now a Student"
end
routes.rb:
post 'assign_as_student' => 'teachers#assign_as_student'
Ok, this WORKS. But...
This was what I had to settle for, because I didn't know how to pass an argument into the controller method.
I wanted to write a method in the UsersController like the above one but with an argument like this (I think this would work, but haven't been able to test it):
def assign_as_type(type)
#user = User.find(params[:user_id])
#user.update_attributes(type: type)
#user.save
redirect_to admin_path, notice: "They are now a Student"
end
This way, I would be able to just have this one method instead of having an "assign_as_student" method AND an "assign_as_teacher" method. Always good to be DRY.
So... I think the above method would work, but how would I pass the argument in from the form? Like the below form, but with something added that would pass in a string "Student" or "Teacher":
<%= form_tag assign_as_type_path do %>
<%= hidden_field_tag :user_id, #user.id %>
<%= submit_tag "Assign as a (Student/Teacher), data: { confirm: "Are you sure?" } %>
<% end %>
(In this answer I assume you are using Rails 4+, otherwise some of my suggestions might not apply, it is good to supply this in the question.)
To pass another argument into the controller you could do:
<%= form_tag assign_as_type_path do %>
<%= hidden_field_tag :user_id, #user.id %>
<%= select_tag :type, options_for_select([ "Student", "Teacher" ]) %>
<%= submit_tag "Assign", data: { confirm: "Are you sure?" } %>
<% end %>
The parameter should then be accessible as params[:type].
Since this is an action on a #user-object I think you should do like this:
<%= form_for #user, url: assign_as_type_path do |f[ %>
<%= f.select :type, options_for_select([ "Student", "Teacher" ],#user.type) %>
<%= f.submit "Assign", data: { confirm: "Are you sure?" } %>
<% end %>
And also in your controller I think you should do like this:
(Here assuming that you changed to form_for)
def assign_as_type(type)
#user = User.find(params[:id])
if #user.update(type: params[:user][:type]) # This sets attribute + saves
redirect_to admin_path, notice: "They are now a " + #user.type
else
redirect_to admin_path, error: "User could not be updated."
end
end
This way, you can use model validation and if you do the redirect as in a normal update action you can also show errors in the form.
Hope this helps, if there is any questions, just ask 😄
Updated answer with params
The way I understood params (and understand if something is wrong) is by looking at your latest request in the Server log (if you are running it locally it is where you started rails s).
Here you would see:
params: { user_id: 1, type: "Student" , commit: "Assign"}
and some other extra parameters.
This is a normal Ruby Hash called params. To get into the Ruby-language you can do the: http://tryruby.org/ tutorial 😄
If you change it to form_for your params hash will look like:
params: { user: { id: 1, type: "Student" }, commit: "Assign" }
Ref:
http://ruby-doc.org/core-2.2.0/Hash.html
I've tried a lot to delete a record from my DB, but I have failed. Instead of deleting the selected value it is inserting a new empty record into my db. Please help me out.
My Controller is:
class CatvaluesController < ApplicationController
...
def destroy
#catvalue = Catvalue.find(params[:id])
#catvalue.destroy
redirect_to catvalues_path
end
....
end
and my form is:
<%= form_for(#catvalue) do |f| %>
<%= f.collection_select :id, #catvalues, :id, :v_name, {}, class: 'drop-down'%>
<%= f.submit 'Destroy', :confirm => 'Are you sure you want to destroy your account?' %>
<% end %>
form_for by default takes post method
<%= form_for #catvalue, :method => :delete do |f| %>
Okay, so I'm now adding url to the form helper, try this one!
<%= form_for #catvalue, :url => "/catvalues/#{#catvalue.id}",:method => :delete do |f| %>
You are submitting a POST request, it will call the create action on your controller hence your empty model.
You have to use the delete http method to call the destroy action on your controller :
<%= form_for(#catvalue, :method => :delete) do |f| %>
I am trying to set up a form in a Rails view to submit an id back to the show method in the controller. My form uses autocomplete to set the hidden id field:
<%= form_tag students_path, id: 'search_student_name', method: :get do %>
<%= text_field_tag :search_name, '', size: 30 %>
<%= hidden_field_tag :id %>
<%= submit_tag "Search", name: nil %>
<% end %>
I'm using the standard controller 'show' method generated by the scaffold:
# GET /students/1
# GET /students/1.json
def show
#student = student_scope.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #student }
end
end
I'd be grateful for any advice on the combination of form url / post method / additional routes to get this to work. Is this the way you'd normally do this is Rails, or should I set up a new controller method to handle the submitted form?
Thanks in advance
Because it is not exactly a Restful show, you should create a new action, search.
#routes.rb
post 'search' => 'students#search'
#student_controller.rb
def search
#student = Student.find_by_name params[:search_name]
render action: 'show'
end
The form doesn't need to send the :id as far as I can tell.
<%= form_tag search_path, method: :get do %>
<%= input_tag :search_name, type: 'text' %>
<%= submit_tag "Search" %>
<% end %>