How to edit model on show view of other model - ruby-on-rails

I have the model Customer, and binded by has_many model Location. This is customer and his locations (adresses). After creating a new customer application redirects on show view of Customer model (shows all data just entered). On show view I have form for location add. There are already entered locations shows on this view and each of them has the link to edit each separate location. I need, when user click on location edit link, he redirects to show view of Customer model, but the form already contains the data of clicked location. Show view code of Customer model:
<p>Customer info:<br>
<strong><%= #customer.name %></strong><br />
<%= #customer.kind.name %><br />
<%= #customer.adres %><br />
<%= #customer.phone %><br />
<%= #customer.comment %><br />
</p>
<h3>Delivery location:</h3>
<% if #locations %>
<ul>
<% #locations.each do |loc| %>
<li>
<%= loc.adres %>
<%= loc.phone %>
<%= loc.comment %>
</li>
<% end %>
</ul>
<% end %>
<%= form_for Location.new do |l| %>
<%= l.text_field :adres %><br>
<%= l.text_field :phone %><br>
<%= l.text_field :comment %><br>
<%= l.text_field :customer_id, type: "hidden", value: #customer.id %><br>
<%= l.submit "Add" %>
<% end %>
<%= link_to "Home", root_path %>

You'd just set #location depending on whether specific params have been sent:
#app/controllers/customers_controller.rb
class CustomersController < ApplicationController
def show
#customer = Customer.find params[:id]
#location = params[:location_id] ? #customer.locations.find(params[:location_id]) : #customer.locations.new
end
end
This would allow you to populate the form as follows:
#app/views/customers/show.html.erb
Customer info:<br>
<%= content_tag :strong, #customer.name %>
<%= #customer.kind.name %>
<%= #customer.adres %>
<%= #customer.phone %>
<%= #customer.comment %>
<h3>Delivery location:</h3>
<% if #customer.locations %>
<ul>
<% #customer.locations.each do |loc| %>
<%= content_tag :li do %>
<%= loc.adres %>
<%= loc.phone %>
<%= loc.comment %>
<%= link_to "Edit", customer_path(#customer, location_id: loc.id) %>
<% end %>
<% end %>
</ul>
<% end %>
<%= form_for #location do |l| %>
<%= l.text_field :adres %><br>
<%= l.text_field :phone %><br>
<%= l.text_field :comment %><br>
<%= l.text_field :customer_id, type: "hidden", value: #customer.id %><br>
<%= l.submit %>
<% end %>
--
To manage the routes (to pass location_id), you'll be best creating a custom route:
#config/routes.rb
resources :customers do
get ":location_id", on: :member, action: :show, as: :location #-> url.com/customers/:id/:location_id
end
This will mean you'll have to reference the other link in your view:
<%= link_to "Edit", customer_location_path(#customer, loc.id) %>

Related

Rails - Couldn't find Student with 'id'=

I'm getting the error above when I try to create a a 'mark' for a 'student'. I can't figure out how to pass the :student_id when I create a new mark.
Routes
Rails.application.routes.draw do
resources :students do
resources :marks
end
resources :marks
root 'students#index'
Marks Controller
class MarksController < ApplicationController
def create
#student = Student.find(params[:student_id])
#mark = #student.marks.create(params[:input1, :input2, :input3, :weight1, :weight2, :weight3, :mark1, :mark2, :mark3, :final_mark].permit(:input1, :input2, :input3, :weight1, :weight2, :weight3, :mark1, :mark2, :mark3, :final_mark))
#mark.save
if #mark.save
redirect_to student_path(#student)
else
render 'new'
end
end
def new
#mark = Mark.new
end
private
def set_mark
#mark = Mark.find(params[:id])
end
end
Students Show View
<p id="notice"><%= notice %></p>
<p>
<strong>Student Number</strong>
<%= #student.StudentNumber %>
</p>
<p>
<strong>Project Title</strong>
<%= #student.ProjectTitle %>
</p>
<p>
<strong>Project PDF</strong>
<%= #student.ProjectTitle %>
</p>
<p>
<strong>Reader 1</strong>
<%= #student.Reader1 %>
</p>
<p>
<strong>Reader 2</strong>
<%= #student.Reader2 %>
</p>
<h3> <%= link_to 'Add Mark', new_student_mark_path(#student), class:"btn btn-warning"%> </h3>
<p>
<strong>Reader 3</strong>
<%= #student.Reader3 %>
</p>
<%= link_to 'Edit', edit_student_path(#student) %> |
<%= link_to 'Back', students_path %>
Marks Form
<%= form_for #mark, html: {multipart: true} do |f| %>
<% if #mark.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#mark.errors.count, "error") %> prohibited this grading from being saved:</h2>
<ul>
<% #mark.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label 'Introduction' %><br>
<%= f.text_area :input1 %>
<%= f.number_field :weight1 %>
<%= f.number_field :mark1 %>
</div>
<div class="field">
<%= f.label 'Main' %><br>
<%= f.text_area :input2 %>
<%= f.number_field :weight2 %>
<%= f.number_field :mark2 %>
</div>
<div class="field">
<%= f.label 'Conclusion' %><br>
<%= f.text_area :input3 %>
<%= f.number_field :weight3 %>
<%= f.number_field :mark3 %>
</div>
<div class="actions">
<%= f.submit class:"btn-xs btn-success"%>
</div>
<% end %>
Mark model
class Mark < ActiveRecord::Base
belongs_to :student
end
Student Model
class Student < ActiveRecord::Base
has_many :marks
has_attached_file :document
validates_attachment :document, :content_type => { :content_type => %w(application/pdf) }
end
It's probably something really stupid but if anyone could explain the problem I'd be really grateful.
Thanks
I don't suggest you using hidden fields for this purpose.
You should pass student together with mark into form_for helper and rails will generate proper url for you which will look like: /students/:student_id/marks
In this case it will be possible to extract student_id from params in your action later.
form_for [#student, #mark], html: {multipart: true} do |f|
More information about nested resources:
http://guides.rubyonrails.org/routing.html#nested-resources
http://www.informit.com/articles/article.aspx?p=1671632&seqNum=7
https://gist.github.com/jhjguxin/3074080
UPDATE:
Forgot to mention that in order to make this work you need to pass student instance into your template at new action:
def new
#student = Student.find(params[:student_id])
#mark = #student.marks.build
end

Gem dragonfly. How to make the list of current files on edit view?

I have model Project and in model have field documents(files). I am using gem dragonfly. When editing a project, how to make the list of current files? At this time on the edit page the list of files fields show: "The file is not selected". I do next: ​
projects_controller:
def edit
end
def update
if #project.update(project_params)
redirect_to #project
else
render :edit
end
end
private
def set_project
#project = Project.find(params[:id])
end
def set_payment_types
#payment_types = PaymentOption.all
end
def project_params
params.require(:project).permit(:title, :description, :price, :location,
:anonymity, :price_category, :category_id, :skill_list, documents_attributes: [:attachment], payment_option_ids: [])
end
edit.html.erb:
<%= form_for #project do |f| %>
<p>
<%= f.label 'Name' %>
<%= f.text_field :title %>
</p>
<P>
<%= f.label 'Budget' %>
<%= f.text_field :price %>
für
<%= f.select :price_category, Project::PRICE_CATEGORIES %>
</P>
<p>
<%= f.label 'Description' %>
<%= f.text_area :description %>
</p>
<p>
<%= f.label 'Category' %>
<%= f.collection_select :category_id, Category.all, :id, :name %>
</p>
<p>
<%= f.label 'Skills Freelancer (15 pieces) *' %>
<%= f.text_field :skill_list %>
</p>
<p>
<%= f.label 'Location' %>
<%= f.text_field :location %>
</p>
<ul>
<% #payment_types.each do |type| %>
<li><%= check_box_tag 'project[payment_option_ids][]', type.id %>
<%= type.name %>
</li>
<% end %>
</ul>
<p>
<b>Anonymity order</b>
</p>
Setup allows for players to remain anonymous. Note that this may reduce the number of responses.
<p>
<%= f.label 'Place Order anonymously' %>
<%= f.check_box :anonymity %>
</p>
<p>
<%= f.fields_for :documents do |d| %>
<%= render 'document_fields', f: d %>
<% end %>
<div class="links">
<%= link_to_add_association 'add file', f, :documents %>
</div>
</p>
<P>
<%= f.submit 'Edit' %>
</P>
<% end %>
​_document_fields.html.erb:
<div class="nested-fields">
<%= f.label :attachment %>
<%= f.file_field :attachment %>
<%= link_to_remove_association "remove file", f %>
</div>
document.rb
class Document < ApplicationRecord
belongs_to :project
dragonfly_accessor :attachment
end
On the edit page the list of files fields show: "The file is not selected", but must be specified ​current files.
file_field is for uploading new files only, not for displaying what is already in the database. For displaying a list of uploaded files, you should just display the name of the file and/or an image tag with the thumbnail and provide a destroy link.
You can also provide a link to create a new attachment.
edit.html.erb
<div>
<ul>
<%= #project.documents.each do |document| %>
<li>
<%= document.attachment.name %>
<%= link_to "Delete", document_path(document), method: :delete, data: { confirm: 'Are you sure you want to delete this?' } %>
</li>
<% end %>
</ul>
<div class="links">
<%= link_to_add_association 'add file', f, :documents %>
</div>
</div>

Ruby on Rails, instead of update make new entry to model

I made a simple demo site, with an model for the patients name (name:string) and another model with the treatment (content:text). I created this "project" to learn more about the accepts_nested_attribute for tag and the fields_for tag.
Now my problem is that on the patient show page i created an nested formula for the treatment , like you can see here:
<p id="notice"><%= notice %></p>
<p>
<b>Name:</b>
<%= #patient.name %>
</p>
<ol>
<% for treatment in #patient.treatments %>
<li><%= treatment.content %></li>
<% end %>
</ol>
<%= form_for(#patient) do |f| %>
<%= f.fields_for :treatments do |builder| %>
<div class="field">
<%= builder.label :content %><br />
<%= builder.text_field :content %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<%= link_to 'Edit', edit_patient_path(#patient) %> |
<%= link_to 'Back', patients_path %>
So my problem is that in the builder.text_field :content better called the input shows up the last saved treatment from <%= builder.content %>, but i want that he does not update it instead i want to add new treatments! Hopefully somebody understands me! Thanks
I would create separate controller for creating only the treatment, eg.
# treatments_controller.rb
class TreatmentsController < ApplicationController
def create
#patient = Patient.find(params[:patient_id])
#treatment = #patient.treatments.new(params[:treatment])
if #treatment.save
redirect_to #patient
else
# handle unsuccessful treatment save
end
end
end
# routes.rb:
resources :patients do
resources :treatments, only: :create
end
# form:
<%= form_for #patient, #treatment do |f| %>
<div class="field">
<%= f.label :content %><br />
<%= f.text_field :content %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
You should also set #treatment variable in the patient#show action, like this:
#treatment = #patient.treatments.new

NoMethodError in Pages#contact

I got this error I Created pages model and for pages controller i created a contact, thank you and _form page. but I getting the error "NoMethodError in Pages#contact"
`Showing /home/rohit/Desktop/inertiiaproject/inertiiatwo/app/views/pages/_form.html.erb where line #1 raised:
undefined method model_name' for NilClass:Class
pages_controller.rb file
class PagesController < ApplicationController
def new
#pages = pages.new
end
def create
#pages = pages.new(params[:pages])
if #pages.deliver
render :thank_you
else
render :new
end
end
end
contact.html.erb
<h1>Want to get in touch?</h1>
<p>Please fill out the form below and we'll get back to you as soon as possible.</p>
<%= render 'form', :pages => #pages %>
_form.html.erb
<%= form_for pages do |f| %>
<% if pages.errors.any? %>
<ul>
<% pages.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
<% end %>
<div style="display: none;">
<%= f.label :nickname %><br/>
<%= f.text_field :nickname %>
</div>
<div>
<%= f.label :name %><br/>
<%= f.text_field :name %>
</div>
<div>
<%= f.label :email %><br/>
<%= f.text_field :email %>
</div>
<div>
<%= f.label :message %><br/>
<%= f.text_area :message %>
</div>
<div>
<%= f.submit "Send" %>
</div>
<% end %>

How to use If,else in form_for helper to extract specific field

I have following code in my edit view:
<%= form_for #content do |f|%>
<% if f.text_field :home %>
<%= f.label :Home %>
<%= f.text_field :home %>
<% elsif f.text_field :aboutus %>
<%= f.label :Abouts %>
<%= f.text_field :aboutus %>
<% end %>
<%= f.submit%>
Here #content contain following information:
id: "1", home: "staticcontent", aboutus: "staticcontent"
so i wants that if someone wants to edit home page he can see only home submission form and if he choose aboutus, he can see edit form page for only about us.suggest me whats correct way to use if,else in this block?
You could pass a URL param and work with that. For example:
# in some view
<%= link_to "Edit Homepage", edit_content_path(page: "home")
# this will link to /contents/:id/edit?page=home
Then in your form:
<%= form_for #content do |f|%>
<% if params[:page] == "home" %>
<%= f.label :home %>
<%= f.text_field :home %>
<% else %>
<%= f.label :about_us %>
<%= f.text_field :about_us %>
<% end %>
<%= f.submit%>
Notice I downcased the labels, and changed aboutus to about_us so that the label displays correctly.

Resources