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 %>
Related
I'm using gem 'ransack' to search records.
The page I'm programming starts with ONLY a dropdown to select #department.
After that, I want Ransack to search within #department.
I need to include an additional parameter department=2 with the Ransack search parameters. (It works if I insert that into the browser URL).
Browser URL after I type in department=2
http://localhost:5000/departments/costfuture?department=2&utf8=%E2%9C%93&q%5Bid_eq%5D=&q%5Bproject_year_eq%5D=&q%5Boriginal_year_eq%5D=&q%5Bclient_id_eq%5D=43&q%5Blocation_name_cont%5D=&q%5Bproject_name_cont%5D=&q%5Bcoststatus_id_in%5D%5B%5D=&q%5Bcoststatus_id_not_in%5D%5B%5D=&q%5Brebudget_true%5D=0&q%5Bnew_true%5D=0&q%5Bconstruction_true%5D=0&q%5Bmaintenance_true%5D=0&commit=Search
This is the controller:
def costfuture
#departments = current_user.contact.departments
if params[:department]
#department = Department.find(params[:department])
#search = #department.costprojects.future.search(params[:q])
#costprojects = #search.result.order(:department_priority)
end
respond_to do |format|
format.html # index.html.erb
format.json { render json: #departments }
end
end
I tried this in the view:
<%= search_form_for #search, url: departments_costfuture_path(:department => #department.id) do |f| %>
But, the resulting URL is missing the department=2.
If you want to pass the department option through to Ransack, you can do this with a hidden field within your search_form_for:
<%= search_form_for #search, url: departments_costfuture_path do |f| %>
<%= f.hidden_field :department_eq, value: #department.id %>
<%# Other form code here %>
<% end %>
But if you want to search a particular department, then it's better to use Rails routes for that. You can generate URLs like /departments/2/costfuture by modifying config/routes.rb:
resources :departments do
get 'costfutures', on: :member
end
Now you can use the resulting URL helper to generate links that will set params[:id], and you can use that to retrieve #department.
I ended up using hidden_field_tag inside search_form_for.
<%= search_form_for #search, url: departments_costfuture_path do |f| %>
<%= hidden_field_tag :department, #department.id %>
<%= f.search_field :last_name_or_first_name_cont %>
<% end %>
Then params[:department] and params[:search] will be accessible in the controller.
I have a method called "createpost" in "topics_controller" which I am trying access from the show inside "topics_controller" but I keep getting a route error.
The Form:
<%= form_for #community_post, :url => { :action => "createpost", :controller=> "community_topics" } do |f| %>
<%= render 'error_messages' %>
<%= f.label :text %>
<%= f.text_area :text %>
<%= hidden_field_tag :community_topic_id, #community_topic.id %>
<br>
<%= f.submit "Submit reply" %>
The Controller Action:
def createpost
#community_post = CommunityPost.new(community_post_params)
#community_post.user_id = current_user.id
#community_post.community_topic_id = params[:community_topic_id]
if #community_post.save
redirect_to "/community_topics/#{#community_post.community_topic_id}", notice: 'Community post was successfully created.'
else
render action: 'new'
end
end
What am I doing wrong so I can correct it? Thanks a bunch.
You should have in your routes something like:
resources :comunity_topics do
post 'createpost', action: 'createpost'
end
and the form route should be something like:
createpost_comunity_topics_path
Either rename the method createpost in controller to create and remove the url option for form_for in view. Or define the route, if you really want use the createpost action like this:
resources :community_posts do
collection do
post :createpost
end
end
But I suspect that you are following some old tutorial from the times when Rails had routes that contained the name of controller and action to be executed. This approach was abandoned in favor of RESTful routes.
Read the current docs here:
http://guides.rubyonrails.org/routing.html#resource-routing-the-rails-default
I have created a search form
<%= form_tag url_for(:action => "index") do %>
<%= text_field_tag 'fromdate' %>
<%= text_field_tag 'todate' %>
<%= submit_tag 'Search' %>
<% end %>
I need to pass all these values as a single params in my controller to model. This is my controller
def index
#client = Customer.search
#something like this #client = Customer.search(as_single_params)
respond_to do |format|
format.html
end
end
How can I do this?
You can do this in your view:
<%= text_field_tag "some_fields[]" %>
<%= text_field_tag "some_fields[]" %>
<%= text_field_tag "some_fields[]" %>
Then in your controller simply retrieve the values using:
some_fields = params[:some_fields] # this is an array
If you pass values as keys, Rails will give you a Hash:
<%= text_field_tag "some_fields[fromdate]" %>
<%= text_field_tag "some_fields[todate]" %>
In your controller you can do this now:
#clients = Customer.search(params[:some_fields])
^
I added an s to #client since you'll have probably more than one clients matching your criteria.
When you submit your form, all of the parameters you selected will be passed to the controller in the params hash. For example, params[:fromdate] and params[:todate].
In your controller, if your params hash contains only Customer fields you want to search on (i.e., the form only has Customer fields defined, then you can do:
def index
#clients = Customer.where(params)
respond_to do |format|
format.html
end
end
Note that I show #clients since where will return a collection. You can select the first one (especially if you're sure there's only one) by doing this:
#client = Customer.where(params).try(:first)
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 %>
I have a template "groups/show.html.erb" I have link that renders a partial by passing a parameter to the controller. The controller then uses the parameter to identify which JS call to make.
<%= link_to 'Add a Video', group_path(create_video: true), remote: true %>
then in the controller
elsif params[:create_video]
#video = Group.find(params[:id]).videos.build
respond_to do |format|
format.js {render action: 'create_video'}
end
This brings up a partial with a form that creates a video using the create method in the videos_controller. If a validation on the form fails and I try to render "groups/show" I get a routing error:
_create_video.html.erb
<%= form_for #video, :url => group_videos_path(#group) do |f| %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
No route matches {:action=>"show", :controller=>"groups", :create_video=>true}
To make this work I think you can just explicitly match it in routes.rb but is there a better way to do it? Thanks a bunch
You are forgetting to give which group, you should normally do something like
group_path(#group, create_video: true)
hope this helps.