ruby on rails - Do Loop in a controller - ruby-on-rails

I would like to display every files that belong to one given project (the relationship works fine, could check it using the Rails console).
Here is my 'Project' controller , I may need a do loop (to loop through each files , for 1 project) but I'm not sure :
def show
#project = Project.find(params[:id])
#pfile = Project.find(params[:id]).Pfiles.find(:all)
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #project }
format.xml { render :xml => #pfile }
end
end
This is my 'Project' view :
<p id="notice"><%= notice %></p>
<p>
<b>Name:</b>
<%= #project.name %>
</p>
<p>
<b>Description:</b>
<%= #project.description %>
</p>
<p>
<b>Files:</b>
<%= #project.pfile.name %>
</p>
<%= link_to 'Edit', edit_project_path(#project) %> |
<%= link_to 'Back', projects_path %>
Thanks :)

If the relationship is set up correctly you can do this:
controller
#pfiles = #project.pfiles
view
<p>
<b>Files:</b>
<% #pfiles.each do |pfile| %>
<%= pfile.name %>
<% end %>
</p>

easier yet... rely on the magic of rails.
in the controller
#project = Project.find(params[:id])
#pfiles = #project.pfiles
then in the view
<b>Files:</b>
<%= render #pfiles %>
then in views/pfiles/_pfile.html.erb
<%= pfile.name %>

Related

How can I make follow form work with a list

I have a relationship model that follow users back n forth
now it works very well when I use it in users#show in my view just like this screenshot
now this works good but what I have is a list of users.. and with that list I want to render similar type of follow form next to every item in list
here is the screenshot for reference
but of course this doesn't work because in my relationship controller I am finding user/amitian to follow with their id in params[:id] as in show page i have it but in my list page i don't
here is the code in controller for reference
def create
#amitian = Amitian.find(params[:followed_id])
current_amitian.follow(#amitian)
respond_to do |format|
format.html { redirect_to #amitian }
format.js
end
end
def destroy
#amitian = Relationship.find(params[:id]).followed
current_amitian.unfollow(#amitian)
respond_to do |format|
format.html { redirect_to #amitian }
format.js
end
end
is there any solution for this so that I can render a follow_form in my listpage
it doesn't matter even if i have to render a new follow_form.. it just i want follow mechanism to work even from list page rather than only from show page of every user.
here is the show form in my show page..
show_form
<%if amitian_signed_in?%>
<% if #amitian != current_amitian %>
<div id="follow_form">
<% if current_amitian.following?(#amitian) %>
<%= render 'unfollow' %>
<% else %>
<%= render 'follow' %>
<% end %>
</div>
<% end %>
<%end%>
follow_form
<%if amitian_signed_in?%>
<%= form_for(current_amitian.active_relationships.build , remote: true ) do |f| %>
<div><%= hidden_field_tag :followed_id, #amitian.id %></div>
<%= f.submit "Follow", class: "btn btn-primary form-control" %>
<% end %>
<%end%>
unfollow form
<%if amitian_signed_in?%>
<%= form_for(current_amitian.active_relationships.find_by(followed_id: #amitian.id), remote: true,
html: { method: :delete }) do |f| %>
<%= f.submit "Unfollow", class: "btn btn-danger form-control" %>
<% end %>
<%end %>

Rails: Undefined local variable or method `form' in rails 4.1

In my _form partial I render another partial like below
<%= render :partial => 'test', :object => #application.type, \
:locals => {:form => form, \
:application_type => "application[type]"} %>
When I try to load the form I get this error
undefined local variable or method `form' for #<#<Class:0x6daf2c8>:0x8dd3c80>
My test partial
<%= fields_for application_type, application do |application_f| %>
<div>
<div>
<%= application_f.label :uni_id, "University" %>
<%= application_f.collection_select :uni_id, #unis, :id, :check, {:include_blank => true} %>
</div>
</div>
<div>
<% end %>
I recently updated to rails 4.1 from 3.2. It was working before but now it shows error. I guess it is syntax error but could not solve it.
Maybe you need to replace something like this, in your top-level template:
<%= render partial: "form", form: form %>
or like this:
<%= render partial: "form", object: form %>
with something like this (the locals parameter is required now)
<%= render partial: "form", locals: { form: form } %>
Quite a few errors:
<%= render partial: 'test', locals: {form: form }, object: #application %>
<%= form.fields_for application.type, application do |application_f| %>
<div>
<div>
<%= application_f.label :uni_id, "University" %>
<%= application_f.collection_select :uni_id, #unis, :id, :check, {:include_blank => true} %>
</div>
</div>
</div>
<% end %>
This should provide the correct syntax for you.
The error is down to the form variable not being populated. This seems to be from the <%= render call. Without context, the best fix I can give is how it should look:
<%= form_for #variable do |form| %>
<%= render partial: "test", locals: {form:form}, object: #application %>
<% end %>
I experienced this same issue when working on a Rails 6 application
I did an overriding of my routes due to some conflicts from
resources :sessions
to
resources :sessions, as: :sets
Here's how I fixed it:
app/views/sessions/new.html.erb
<h1>New Session</h1>
<%= form_with(model: #session, url: sets_path, local: true) do |form| %>
<%= render partial: 'form', session: #session, locals: { form: form } %>
<% end %>
<%= link_to 'Back', sets_path %>
Note: A URL was defined for the New Form since routing override was done. Thus, the form_with container was isolated from the _form.html.erb partial. This is in a bid to avoid creating multiple _form.html.erb partials for the new.html.erb and edit.html.erb files, since they have different URLs.
app/views/sessions/edit.html.erb
<%= form_with(model: #session, url: set_path(#session), local: true) do |form| %>
<%= render partial: 'form', session: #session, locals: { form: form } %>
<% end %>
<%= link_to 'Show', set_path(session) %> |
<%= link_to 'Back', sets_path %>
Note: A URL was defined for the New Form since routing override was done. Thus, the form_with container was isolated from the _form.html.erb partial. This is in a bid to avoid creating multiple _form.html.erb partials for the new.html.erb and edit.html.erb files, since they have different URLs.
app/views/sessions/_form.html.erb
<% if #session.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#session.errors.count, "error") %> prohibited this session from being saved:</h2>
<ul>
<% #session.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :name %>
<%= form.text_field :name %>
</div>
<div class="field">
<%= form.label :prefix %>
<%= form.text_field :prefix %>
</div>
<div class="actions">
<%= form.submit %>
</div>
Note: Notice that there is no form helper definition in the _form.html.erb file, it was moved to the new.html.erb and edit.html.erb files, since they now have different URLs due to the modification of their route.
app/views/sessions/index.html.erb
<p id="notice"><%= notice %></p>
<h1>Sessions</h1>
<table>
<thead>
<tr>
<th>Name</th>
<th>Prefix</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #sessions.each do |session| %>
<tr>
<td><%= session.name %></td>
<td><%= session.prefix %></td>
<td><%= link_to 'Show', set_path(session) %></td>
<td><%= link_to 'Edit', edit_set_path(session) %></td>
<td><%= link_to 'Destroy', set_path(session), method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Session', new_set_path %>
Note: Pay attention to the modification of the link URLs in the new action.
app/views/sessions/show.html.erb
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= #session.name %>
</p>
<p>
<strong>Prefix:</strong>
<%= #session.prefix %>
</p>
<%= link_to 'Edit', edit_session_path(#session) %> |
<%= link_to 'Back', sessions_path %>
Note: Pay attention to the modification of the link URLs in the edit and back actions.
app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
before_action :set_session, only: [:show, :edit, :update, :destroy]
# GET /sessions
# GET /sessions.json
def index
#sessions = Session.all
end
# GET /sessions/1
# GET /sessions/1.json
def show
end
# GET /sessions/new
def new
#session = Session.new
end
# GET /sessions/1/edit
def edit
end
# POST /sessions
# POST /sessions.json
def create
#session = Session.new(session_params)
respond_to do |format|
if #session.save
format.html { redirect_to sets_path(#sesion), notice: 'Session was successfully created.' }
format.json { render :show, status: :created, location: sets_path(#sesion) }
else
format.html { render :new }
format.json { render json: #session.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /sessions/1
# PATCH/PUT /sessions/1.json
def update
respond_to do |format|
if #session.update(session_params)
format.html { redirect_to sets_path(#sesion), notice: 'Session was successfully updated.' }
format.json { render :show, status: :ok, location: sets_path(#sesion) }
else
format.html { render :edit }
format.json { render json: #session.errors, status: :unprocessable_entity }
end
end
end
# DELETE /sessions/1
# DELETE /sessions/1.json
def destroy
#session.destroy
respond_to do |format|
format.html { redirect_to sets_url, notice: 'Session was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_session
#session = Session.find(params[:id])
end
# Only allow a list of trusted parameters through.
def session_params
params.require(:session).permit(:name, :prefix)
end
end
Note: Pay attention to the modification of the redirect URLs in the create and update actions.
That's all.
I hope this helps

Rails: Will_paginate does not work properly after AJAX call

Sorry about the repetition, I could not find the answers to my questions after a lot of searches. The will_paginate does not work after the Ajax call.
After delete action, It does not display the pages numbers at all (it simply returns all results).
After search action, the page number does not update, it shows more pages than what should actually be there.
Here is the controller code.
class CitiesController < ApplicationController
def index
#cities = City.get_cities(params[:city_name],params[:city_population]).paginate(:page => params[:page])
respond_to do |format|
format.html
format.js
end
end
def create
#city = City.new(params[:city])
if #city.save
flash[:success] = "City information saved successfully"
redirect_to cities_path
else
render 'index'
end
end
def new
#city = City.new
end
def destroy
#city = City.find(params[:id]).destroy
#city.destroy
#cities = City.all
respond_to do |format|
format.html {redirect_to cities_path}
format.js
end
end
end
Here is the index view:
<div class="row">
<h1>Search Cities or <%= link_to "Create New City", new_city_path %></h1>
<h3>99 random city information are generated in the database </h2>
<h3>Simply type any letter or city population between 0 and 10 to filter out</h3>
<%= form_tag "/cities/index", method: :get, remote: true do %>
<%= label_tag(:q, "City Name:") %>
<%= text_field_tag 'city_name' %>
<%= label_tag(:q, "City Population greater than, in units of 1 million:") %>
<%= text_field_tag 'city_population' %>
<label></label>
<%= button_tag("Search", :class => "btn") %>
<% end %>
<% flash.each do |key, value| %>
<div class="alert alert-<%= key %>"><%= value %></div>
<% end %>
<div id='table' class="table table-striped">
<%= render 'table' %>
</div>
<%=will_paginate #cities %>
</div>
Here is the partial view of the table:
<div class="row">
<h1>Enter City descriptions or <%= link_to "Search Cities", cities_path %></h1>
<%= form_for #city, html: {multipart: true} do |f| %>
<%= f.label :city_name %>
<%= f.text_field :city_name %>
<%= f.label :city_description %>
<%= f.text_field :city_description %>
<%= f.label :city_population_in_units_of_millions %>
<%= f.text_field :city_population %>
<label></label>
<%= f.file_field :image%>
<label></label>
<%= f.submit "Create new City", :class => "btn"%>
<% end %>
</div>
Finally two js.erb codes associated with index and delete actions:
index.js.erb:
$('#table').html('<%= escape_javascript(render('table')) %>');
destroy.js.erb:
$('#table').html('<%= escape_javascript(render('table')) %>');
Found the solution by myself.
add <%= will_paginate #cities %> into partial file
and change #cities = City.all to
#cities = City.all.paginate(page: params[:page])
because will_paginate does not expect an array of objects.
write in your controller
def index
#cities = City.get_cities(params[:city_name],params[:city_population]).paginate(:page => params[:page])
respond_to do |format|
format.html
format.js
end
end
in your view folder create index.js.erb and write
$('id or class').html('<%=escape_javascript render :partial => which part you update %>')

retrieving multiple model objects from rails partial form

I have the below form working as a partial, i'm trying to do a partial call for a Contractors models and i want to also pass the current page's model id which is a quote id.
Its failing on this line <%= hidden_field_tag :quote_id, #quote.id %> 'called id for nil'
I've tried creating a manual route and putting the search on a seperate method, but then i get a template error so i'm just leaving it in the index method for now.
Form in show.html.erb:
<%= form_tag quotes_path, :method => 'get', :id => "contractors_search" do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
</p>
<br><br><br>
<div id="contractors"><%= render 'contractors' %></div>
<% end %>
_contractors.html.erb
<table>
<% #contractors.each do | contractor | %>
<tr>
<td><%= contractor.firstname %></td>
<td>
<%= form_tag (quote_add_contractor_path) do %>
<%= hidden_field_tag :quote_id, #quote.id %>
<%= hidden_field_tag :contractor_id, contractor.id %>
<%= submit_tag "Add" %>
<% end %>
</td>
</tr>
<% end %>
</table>
Index.js.erb
$("#contractors").html("<%= escape_javascript(render :partial => "contractors") %>");
Controller:
def index
#quotes = Quote.all
#contractors = Contractor.search(params[:search])
end
def add_contractor
#quote = Quote.find(params[:quote_id])
#contractor = Contractor.find(params[:contractor_id])
#quote.contractors << #contractor
if #quote.save
redirect_to #quote, notice: "contractor was added"
else
render :show, notice: "Sorry, something went aweful"
end
end
In index.js.erb you render the partial contractors but you do not set the #quote instance variable in your index action of the controller. That is why you are getting this failure. Try to add #quote = # Some logic here to your index action.

No route matches when trying to edit

Here's the scoop: I've created a test app that allows users to create ideas and then add "bubbles" to these ideas. Currently, a bubble is just text. I've successfully linked bubbles to ideas. Furthermore, when a user goes to view an idea it lists all of the bubbles attached to that idea. The user can even delete the bubble for a given idea.
My problem lies in editing bubbles. When a user views an idea, he sees the idea's content as well as any bubbles for that idea. As a result, I've set all my bubble controls (editing and deleting) inside the ideas "show" view. My code for editing a bubble for an idea is <%= link_to 'Edit Bubble', edit_idea_bubble_path %>. I ran rake routes to find the correct path for editing bubbles and that is what was listed.
Here's my error: No route matches {:action=>"edit", :controller=>"bubbles"}
In my bubbles controller I have:
def edit
#idea = Idea.find(params[:idea_id])
#bubble = #idea.bubbles.find(params[:id])
end
def update
#idea = Idea.find(params[:idea_id])
#bubble = #idea.bubbles.find(params[:id])
respond_to do |format|
if #bubble.update_attributes(params[:bubble])
format.html { redirect_to(#bubble,
:notice => 'Bubble was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "Edit" }
format.xml { render :xml => #bubble.errors,
:status => :unprocessable_entity }
end
end
end
To go a step further, I have the following in my routes.rb file
resources :ideas do
resources :bubbles
end
So far everything seems to function except when I try to edit a bubble.
I'd love some guidance.
Thanks!
Here's my show.html.erb file for Ideas:
<h2>Bubbles</h2>
<% #idea.bubbles.each do |bubble| %>
<p>
<b>Bubble:</b>
<%= bubble.description %>
</p>
<p>
<%= link_to 'Edit Bubble', edit_idea_bubble_path (#idea) %>
</p>
<tb />
<p>
<%= link_to 'Delete Bubble', [bubble.idea, bubble],
:confirm => 'Are you sure you want to delete this bubble?',
:method => :delete %>
</p>
<% end %>
<h2>Add a bubble:</h2>
<%= form_for([#idea, #idea.bubbles.build]) do |f| %>
<div class="field">
<%= f.label :description %><br />
<%= f.text_area :description %>
</div>
<div class="actions">
<%= f.submit %> </div><% end %>
Following edit_idea_bubble_path (#idea), here is the edit.html.erb file for Bubbles:
<%= render 'form' %>
<%= link_to 'Back to Ideas', ideas_path %>
And finally, my _form.html.erb file for Bubbles: this is where the problem lies, I believe
<% form_for([#idea, #idea.bubbles.build]) do |f| %>
<%= f.error_messages %>
<div class="field">
<%= f.label :description %><br />
<%= f.text_area :description %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
First build the route in your show.html.erb file
<%= link_to 'Edit Bubble', edit_idea_bubble_path(#idea, bubble) %>
Then, your controller should have 2 objects for both #idea and #bubble
when action is new
#idea = Idea.find_by_id(:params[:idea_id])
#bubble = #idea.bubbles.build
when action is edit
#idea = Idea.find_by_id(:params[:idea_id])
#bubble = #idea.bubbles.find_by_id(:params[:bubble_id])
In your _form.html.erb
<% form_for([#idea, #bubble]) do |f| %>
You have to provide the idea and the bubble objects:
<%= link_to 'Edit Bubble', edit_idea_bubble_path(#idea,#bubble) %>
Update:
Edit the _form.html.erb file
<% form_for([#idea, #bubble]) do |f| %>

Resources