Now I am trying to set a form on the page of index.html.erb(members). I want the form to show the result of searching and want it not to move to other pages. I want to show the result on index.html.erb(members) itself.
But the code below makes the application move to show.html(members) after pushing the search button. I have no idea why this happens. Could you give me some advice?
Now I am trying to set search window based on my textbook. But I failed with the error message below. I don't understand the cause although this is just a syntax error. Could you give me some advice?
☆index.html.erb(members controller)
<h1>Listing users</h1>
<p>※登録されているメンバーのリストです。</p>
<%= form_tag :action => 'index' do %>
<div class = "field">
<%= label_tag 'place', '活動場所:' %><br />
<%= text_field_tag 'place' %>
</div>
<%= submit_tag '検索' %>
<% end %>
<%= #places_field %>
☆members controller
def index
if !checklogin? then return end #
#members = Member.all
#places_field = Member.where("place = ?", params[:place])
respond_to do |format|
format.html # index.html.erb
format.json
end
end
☆routes.rb
MiniSNS::Application.routes.draw do
resources :group_message_comments
resources :group_messages do
resources :group_message_comments
end
root :to => 'members#login'
match '/groups/join'
resources :group_messages
resources :groups do
resources :group_messages
end
match '/members/new'
resources :index
resources :groups
post 'groups/:id' => 'group#show'
post '/groups/new'
post '/index/index'
match '/members/login'
match '/members/logout'
match '/members/friend'
match '/members/show'
post '/messages/comment'
resources :comments
resources :messages
resources :friends
resources :members
#OmniAuth
match "/auth/:provider/callback" => "sessions#callback"
match "/logout" => "sessions#destroy", :as => :logout
match '/auth/failure', to: redirect('/')
First, you have to adding remote => true on your submit_tag like:
<%= submit_tag '検索', :remote => true %>
Then on your controller, adding return to js with:
respond_to do |format|
format.html # index.html.erb
format.json
format.js
end
Create new view called index.js.erb and fill that file with Javascript code to update your place field, the simplest way is like:
On index.html.erb make sure you have this kind of code:
<div id="place_field_section"><%= render 'place_field' %></div>
Of course you should have a partial called _place_field.html.erb for example:
<table>
<tr>
<th>Foo</th>
<th>Bar</th>
</tr>
<% #place_fields.each do |place_field| %>
<tr>
<td><%= place_field.foo %></td>
<td><%= place_field.bar %></td>
</tr>
<% end %>
</table>
then on your index.js.erb:
$("#place_field_section").html("<%= escape_javascript(render('place_field')) %>");
Is this what you intent to? Please correct me if I'm wrong.
Related
I am trying to learn how to use routes and paths in Rails 4.
I have a model called organisation requests.
I have routes in by routes.rb as follows:
resources :organisation_requests do #, only: [ :index, :new, :create ]
member do
put "requested" => "organisation_requests#requested", as: :request_approval #what does this mean?
put "approved" => "organisation_requests#requested", as: :approved #what does this mean?
put "rejected" => "organisation_requests#rejected", as: :not_approved #what does this mean?
put "removed" => "organisation_requests#removed", as: :removed #what does this mean?
end
end
In my organisation requests controller, I have:
def approved
organisation_request = OrganisationRequest.find(params[:id])
authorize #organisation_request
if organisation_request.state_machine.transition_to!(:approved)
flash[:notice] = "You've been added as a member. Welcome aboard."
format.html { redirect_to :index }
# format.json { render :show, status: :ok, location: #project }
# redirect_to action: :show, id: project_id
# add mailer to send message to owner that article has been approved
else
flash[:error] = "You're not able to manage this organisation's members"
redirect_to(profile_path(current_user.profile))
# redirect_to action: :show, id: project_id
end
end
In my organisation requests index, I'm trying to make a path that allows a user to approve a request:
<% #organisation_requests.each do |orgReq| %>
<tr>
<td>
<%#= link_to orgReq.profile.user.full_name, organisation_request.profile_path(organisation_request.profile.id) %>
</td>
<td>
<%= orgReq.created_at.try(:strftime, '%e %B %Y') %>
</td>
<td>
<%= orgReq.current_state %>
</td>
<td>
<% if policy(orgReq).approved? %>
<%= link_to "APPROVE", request_approval_path(#organisation_request), :class=>'btn btn-info', method: :put %>
<% end %>
</td>
</tr>
<% end %>
When I save all this and try it, I expect the approve button to work. Instead I get an error that says:
undefined method `request_approval_path' for #<#<Class:0x007fa470f72968>:0x007fa474d17a98>
I'm not sure where I'm going wrong?
That's because the method name is "request_approval_organisation_request". You're calling that route insine a controller. If you add
get 'exit', to: 'sessions#destroy', as: :logout
Inside your resources :organisation_requests you will get
logout_organisation_request_path
and so on
rake in Rails 4 has a routes command that will allow you to see what your url path helpers are all named as a result of the contents of your routes.rb file.
From your project root, what does rake routes | grep request_approval yield?
I have users that have posts.
<p id="notice"><%= notice %></p>
<h1>Listing Posts</h1>
<table>
<thead>
<tr>
<th>Comment</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #posts.each do |post| %>
<tr>
<td><%= post.content %></td>
<td><%= link_to 'Show', post %></td>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<td><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Post', new_user_post_path %>
And in controller
def destroy
#user = #post.user
#post.destroy
respond_to do |format|
format.html { redirect_to user_posts_url(#user), notice: 'Post was successfully destroyed.' }
format.json { head :no_content }
end
end
What's the proper way to implement a link and controller action to destroy all posts for a particular user?
Edit:
config/routes.rb
resources :users do
resources :posts, shallow: true
end
Edit 2:
resources :users do
#resources :posts, shallow: true
resources :posts, shallow: true do
delete :destroy_all, on: collection
end
end
gives no block given (yield) error
aww my bad.. Just found the error.. forgot to add : to collection
I would pass an array of post IDs only if selected posts need to be deleted. If you want to delete all posts for a particular user, then here's how I would approach it:
config/routes.rb
resources :users do
resources :posts do
delete :destroy_all, on: :collection
end
end
Here, on: :collection means that the route applies to the collection of posts; the route therefore looks like this:
/users/:user_id/posts/destroy_all
You can read more about adding member and collection routes in the Rails Guides:
http://guides.rubyonrails.org/routing.html#adding-more-restful-actions
app/controllers/posts_controller.rb
def destroy_all
user = User.find(params[:user_id])
user.posts.destroy_all
# redirect somewhere
end
app/views/posts/index.html.erb
<%= link_to(
"Delete all posts!",
destroy_all_user_posts_path,
method: :delete
) %>
If you want to delete all posts for the current_user, modify like so:
config/routes.rb
resources :posts do
delete :destroy_all, on: :collection
end
app/controllers/posts_controller.rb
def destroy_all
current_user.posts.destroy_all
# redirect somewhere
end
app/views/posts/index.html.erb
<%= link_to(
"Delete all posts!",
destroy_all_posts_path,
method: :delete
) %>
Hope that helps.
I would create a separate controller method that accepts an array of post ids.
posts_controller.rb
def destroy_all
posts = Post.where(:id => params[:post_ids])
posts.delete_all
redirect_to :back
end
You will also need to supply the ids to the view method.
posts_controller.rb
def index
...
#posts_ids = Post.find(... how ever you need to select all posts...).pluck(:id)
...
end
views/posts/index.html.erb
...
<%= link_to destroy_all_posts_path(:post_ids => #posts_ids), :method => :destroy %>
...
You will also need to supply the route.
routes.rb
resources :users do
resources :posts
delete :destroy_all
end
end
And that should be it :)
You can use:
def destory_posts(user)
user.posts.destroy_all
render :nothing => true
end
add this method to your routes file.
Create a link like destory_posts_path(current_user) from where you want to delete the posts.
Hello i'm new one in ruby on rails. I have strange problem. I use some tutorial and get error which i shouldn't get.
I have controller
class DiaryController < ApplicationController
before_action :authenticate_user!
respond_to :html, :xml, :json
respond_to :js, :only => [:create, :update, :destroy]
def create
#record = Record.create(record_params)
#record.userId=current_user.id
if request.xhr? || remotipart_submitted?
sleep 1 if params[:pause]
render :layout => false, :template => (params[:template] == 'escape' ? 'comments/escape_test' : 'diary/create'), :status => (#record.errors.any? ? :unprocessable_entity : :ok)
else
redirect_to diary_path
end
end
def add
#record = Record.new
#respond_with(#record, :layout => false)
respond_with do |format|
format.html { render :layout => ! request.xhr? }
end
end
# PUT /comments/1
# PUT /comments/1.xml
def update
#record = Record.find(params[:id])
respond_with do |format|
format.html{ redirect_to #record }
end
end
def delete
#comment = Comment.destroy(params[:id])
end
def edit
#record = Record.find(params[:id])
end
def index
#records = Record.where(userId: current_user.id)
end
private
def record_params
params.require(:record).permit(:photo, :comment, :date, :photo_cache)
end
end
Have view
<h1 align="centre">
Добавить запись
</h1>
<%= render 'form' %>
<%= link_to 'Отмена', diary_path, :id => 'cancel-button' %>
and
<%= form_for(#record, :remote => (params[:action] == 'add' ? true : false)) do |f| %>
<fieldset>
<div class="field">
<%= f.label :date, :class => 'required' %><br />
<%= f.date_select :date %>
</div>
<div class="field">
<%= f.label :comment %><br />
<%= f.text_area :comment %>
</div>
<div class="field">
<%= image_tag(#record.photo_url(:thumb)) if #record.photo? %><br />
<%= f.label :photo %><br/>
<%= f.file_field :photo %><br/>
<%= f.hidden_field :photo_cache %>
</div>
</fieldset>
<table>
<tr>
<td>
<div class="actions">
<%= f.submit "Добавить", :data => {:'disable-with' => "Submitting..."} %>
</div>
</td>
<td>
<%= link_to 'Отмена', diary_path, :id => 'cancel-button' %>
</td>
</tr>
</table>
And get ActionView::Template::Error (undefined method `records_path' for #<#:0x000000054461c8>): error on "<%= form_for(#record, :remote => (params[:action] == 'add' ? true : false)) do |f| %>" line. Even records_path i did'n use.
I Have routes
devise_for :users
get 'welcome/index'
root 'welcome#index'
get 'diary' => 'diary#index'
get 'diary/add_record', to: 'diary#add', as: 'add_record'
post 'diary/add_record', to: 'diary#create'
get 'diary/edit_record/:id', to: 'diary#edit'
delete 'diary/edit_record/:id' => 'diary#delete
And and try to use add_record route. Maybe it would be better to use resources :records.But i want to figure out why my routes doesn't work.
view name "diary".
Because you're new to RoR, let me explain why you're receiving the error
form_for
form_for is the likely reason why you're receiving this error (oh, I just saw it actually states this is where the error occurs - sweet)
The problem you have is that form_for is meant as a way to render a form around an ActiveRecord object. It's mean to give some semi-persistence to the data, by using AR in both the new and create actions (allowing you to show the in-putted data on the form after submission)
When you pass an object to form_for, Rails automatically "builds" the form from the ActiveRecord object, one of the options it uses being the url
--
Routes
The problem you have is the object you pass to the form_for takes the model_name attribute to build the route. This means if you want to use the form_for method by just passing an object, it's going to look for routes pertaining directly to that object
If you don't have any [model]_path route set up, you'll likely receive the error you're getting. The fix firstly involves the routes, and secondly involves the controller:
#config/routes.rb
root 'welcome#index'
devise_for :users
resources :diary, path_names: { new: "add_record", create: "add_record", edit: "edit_record", destroy: "edit_record" }
resources :welcome, only: :index
This is down to the idea that Rails' routing structure is built around resources - every route you have should lead to a specific controller action. Whilst including custom actions is completely fine, you have to appreciate that the basis of the routing structure is to construct resourceful routing, which essentially means that Rails perceives every controller / model to have corresponding routes:
--
URL
The second thing to observe is the url of the form
If you have your routes set up as above, and if your routing structure differs from your model structure (different names), you'll want to use the following setup to define the url explicitly:
<%= form_for #record, url: your_custom_path do |f| %>
I am using rails 4.0.0. I am a newcomer to rails and learning rails watching video tutorials and stuck in a problem so need some help.
I have a controller called Subjects and following is the code
Subject Constoller
class SubjectsController < ApplicationController
before_action :set_subject, only: [:show, :edit, :update]
def index
#subjects = Subject.all
end
def list
#subjects = Subject.all
##subjects = Subject.order("subjects.position ASC")
end
def show
#subject = Subject.find(params[:id])
end
def new
#subject = Subject.new(:name => "default")
end
def create
#subject = Subject.new(subject_params)
if #subject.save
redirect_to(:action => 'list')
else
render('new')
end
end
def edit
end
def update
if #subject.update(subject_params)
redirect_to #subject
else
render("edit")
end
end
def delete
#subject = Subject.find(params[:id])
end
def destroy
Subject.find(params[:id]).destroy
redirect_to(:action => "list")
end
private
# Use callbacks to share common setup or constraints between actions.
def set_subject
#subject = Subject.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def subject_params
params.require(:subject).permit(:name, :position, :visible)
end
end
I created a view for the List Action
View for the List Action
<h1>List</h1>
<div class="subject list">
<h2>Subjects</h2>
<table class="listing" summary="Subject list">
<tr class="header">
<th>Position</th>
<th>Subject</th>
<th>Visible</th>
<th>Pages</th>
<th>Actions</th>
</tr>
<% #subjects.each do |subject| %>
<tr>
<td><%= subject.position %></td>
<td><%= subject.name %></td>
<td class="center"><%= subject.visible ? 'Yes' : 'No' %></td>
<td class="center"><%= subject.pages.size %></td>
<td class="actions">
<%= link_to 'Show', subject, :class => 'action show'%>
<%= link_to "Edit", edit_subject_path(subject), :class => 'action edit' %>
<%= link_to "Delete", {:action => 'delete', :id => subject.id}, :class => 'action delete' %>
</td>
</tr>
<% end %>
</table>
</div>
I also have a view for delete and code is as follows
View for Delete Action
<h1>Delete</h1>
<%= link_to("<< Back to List", {:action => 'list'}, :class => 'back-link') %>
<div class="subject delete">
<h2>Delete Subject</h2>
<%= form_for(:subject, :url => {:action => "destroy", :id => #subject.id}) do |f|%>
<p>Are you sure you want to permanently delete this subject?</p>
<p class="reference-name"><%= #subject.name %></p>
<div class="form-buttons">
<%= submit_tag("Delete Subject") %>
</div>
<% end %>
</div>
Here is the configuration of my routes file
SimpleCms::Application.routes.draw do
# 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'
root 'demo#index'
# Example of regular route:
# get 'products/:id' => 'catalog#view'
get 'demo/index'
get 'demo/hello'
get 'demo/other_hello'
#get 'subjects/index'
get 'subjects/list'
get 'subjects/delete'
get '/subjects/:id/destroy' => 'subjects#destroy'
resources :subjects
get 'subjects/show'
get 'subjects/new'
get 'subjects/:id' => 'subjects#show'
# Example of named route that can be invoked with purchase_url(id: product.id)
# get 'products/:id/purchase' => 'catalog#purchase', as: :purchase
# Example resource route (maps HTTP verbs to controller actions automatically):
# resources :products
#resources :subjects
# Example resource route with options:
# resources :products do
# member do
# get 'short'
# post 'toggle'
# end
#
# collection do
# get 'sold'
# end
# end
# Example resource route with sub-resources:
# resources :products do
# resources :comments, :sales
# resource :seller
# end
# Example resource route with more complex sub-resources:
# resources :products do
# resources :comments
# resources :sales do
# get 'recent', on: :collection
# end
# end
# Example resource route with concerns:
# concern :toggleable do
# post 'toggle'
# end
# resources :posts, concerns: :toggleable
# resources :photos, concerns: :toggleable
# Example resource route within a namespace:
# namespace :admin do
# # Directs /admin/products/* to Admin::ProductsController
# # (app/controllers/admin/products_controller.rb)
# resources :products
# end
end
So the main concept is as follows when i will call http://localhost:3000/subjects/list it will show all the subjects and there is also three button that is show, edit and delete and after clicking on the delete link it will go to the delete view and after clicking on the submit button of the form it will be deleting the particular item.
But the main problem is that the form_for in delete view is producing the url in the form action is /subjects/8 where 8 is the id of the subject to be deleted but the url should be /subjects/destroy?id=8 to delete the item but when id is passed along with the action in form_for it produces the wrong url but when only the action is passed it produces the url as /subjects/destroy.
I cannot figure out what is wrong so please help. Thanks to all in advance.
Try a link with delete method instead use a form.
<p>Are you sure you want to permanently delete this subject?</p>
<p class="reference-name"><%= #subject.name %></p>
<%= link_to 'Delete Subject', #subject, method: :delete %>
UPDATE
If you want to use a form for destroy action, try this :
<% form_for #subject, :html => {:method => :delete} do |form| %>
Try this:
<%= form_for(#subject, :url => {:action => "destroy") do |f|%>
Instead of this:
<%= form_for(:subject, :url => {:action => "destroy", :id => #subject.id}) do |f|%>
You don't need to mention the id because in form_for it takes id of the variable mentioned by default.
I'm really really newbie in Ruby on Rails...
I'm trying to make a link to another page in my project, where it's listed the posts that belong to an escuela.
This is what I did:
In posts_controller.rb I wrote:
def postesc
#posts = Post.where(:escuela_id => params[:id])
respond_to do |format|
format.html # postesc.html.erb
format.json { render json: #posts }
end
end
In config/routes.rb I wrote:
match 'postesc' => 'posts#postesc'
In view/escuelas/listaesc.html.erb I wrote the link:
<%= link_to "Escuelas", :controller => "posts", :action => "postesc" %>
And in view/escuelas/postesc.html.erb I want to make a list of the matching posts.
But this page appears just blank, with only the layout.
Please, some help?
First make the association between post and escuela, then you can find it just by
Escuela.find(params[:id]).posts
Change your routes to -
resources :posts do
get 'postesc', :on => :collection
end
View :
<%= link_to "List posts", postesc_posts_path %>
make a change in routes.rb as
get 'postesc' => 'posts#postesc'
try...<%= link_to "Escuelas", postesc_path %>
OR
<%= link_to "Escuelas", { :controller => "posts", :action => "postesc" } %>
you're missing to add an ID for the Escuela to be selected - as you're doing in your Controller#postesc Action (as in words: where: escuela_id => params[:id]).
<%= link_to "Escuela", :controller => "posts", :action => "postesc", :id => 1 %>
but you could use the object-link method using the following syntax (by changing your routes a litte):
# in routes.rb
match 'postesc' => 'posts#postesc', on: :collection, as: 'esc_index'
# in your view
<%- for escuela in #escuelas do %>
<%= link_to "Escuela", esc_index(escueal) %>
<% end %>