I have a program that allows users to enter their song for a certain event. You must enter in the partycode for that event in order for it to submit. Here is a screenshot of what it looks like:
When I submit it gives me this error:
Here is what my SongsController looks like:
class SongsController < ApplicationController
def new
#song = Song.new
end
def create
current_event = Event.find(song_params[:event_id])
#song = current_event.songs.build(song_params)
if #song.save
flash[:success] = "Success"
redirect_to event_path(#song.event)
else
flash[:error] = "Failed"
end
end
def destroy
end
private
def song_params
params.require(:song).permit(:event_id, :artist, :title, :genre)
end
end
event model
class Event < ApplicationRecord
belongs_to :user
validates :name, presence: true
validates :partycode, presence: true, length: {minimum: 5}
has_many :songs, dependent: :destroy
end
song model
class Song < ApplicationRecord
belongs_to :event
validates :artist, presence: true
validates :title, presence: true
end
new.html.erb(song)
<br>
<br>
<h1> Member page </h1>
<div class ="container">
<div class="jumbotron">
<h2> Select an event to add songs to: </h2>
<%= form_for Song.new do |f| %>
<%= f.collection_select(:event_id, Event.all, :id, :name) %>
<h3> Enter your song </h3>
<%= form_for Song.new do |f| %>
<%= f.text_field :artist, placeholder: "Artist" %>
<%= f.text_field :title, placeholder: "Title" %>
<%= f.text_field :genre, placeholder: "Genre" %>
<h2> Enter the partycode for that event: </h2>
<%= form_for Event.new do |f| %>
<%= f.text_field :partycode %>
<%= f.submit "Submit", class: "btn btn-primary" %>
<% end %>
<% end %>
<% end %>
</div>
</div>
What can I do to make this functionality of my website work? Any help is greatly appreciated thanks
I see many form_for nesting on your views. It's impossible. Only one submit for a form.
I think you may want to change your _form.html.erb
<div class ="container">
<div class="jumbotron">
<h2> Select an event to add songs to: </h2>
<%= form_for #song do |f| %>
<%= f.collection_select(:event_id, Event.all, :id, :name) %>
<h3> Enter your song </h3>
<%= f.text_field :artist, placeholder: "Artist" %>
<%= f.text_field :title, placeholder: "Title" %>
<%= f.text_field :genre, placeholder: "Genre" %>
<h2> Enter the partycode for that event: </h2>
<%= f.text_field :partycode %>
<%= f.submit "Submit", class: "btn btn-primary" %>
<% end %>
</div>
</div>
You have completely messed up your form. Ideally you should have one form but here you have just kept one form within another form using form_for.
I would recommend you to have a look at the form_for documentation .
Related
Hello I am back for my second question.
My submit button on my form_for does not do anything when I click on it. I did have an error message in the console that said 'Unpermitted parameter: :photo_cache' however when I saw this I permitted the 'photo_cache' in the params in my controller, BUT the submit button on my form still doesn't work.
Context: I am trying to create a hairdressers which has the following params: name, description, location, photo and address.
Any help would be appreciated, thanks!
My form:
<%= simple_form_for(#hairdresser) do |f| %>
<%= f.error_notification %>
<%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
<!-- [...] -->
<div class="form-inputs">
<%= f.input :name %>
</div>
<div class="form-inputs">
<%= f.input :address %>
</div>
<div class="form-inputs">
<%= f.input :location %>
</div>
<div class="form-inputs">
<%= f.input :description %>
</div>
<div class="form-inputs">
<%= f.input :photo %>
<%= f.input :photo_cache, as: :hidden %>
</div>
<div class="form-actions">
<%= f.button :submit, label: "Submit Form", class: "btn btn-primary" %>
</div>
<!-- [...] -->
<% end %>
My controller:
class HairdressersController < ApplicationController
def index
#hairdressers = Hairdresser.all
end
def show
#hairdresser = Hairdresser.find(params[:id])
end
def new
#hairdresser = Hairdresser.new
end
def create
#hairdresser = Hairdresser.new(hairdresser_params)
# #hairdresser.save ? (redirect_to hairdresser_path(#hairdresser)) : (render 'new')
if #hairdresser.save
redirect_to hairdresser_path(#hairdresser)
else
render 'new'
end
end
def edit
#hairdresser = Hairdresser.find(params[:id])
end
def update
#hairdresser = Hairdresser.find(params[:id])
end
def destroy
#hairdresser = Hairdresser.find(params[:id])
end
end
private
def hairdresser_params
params.require(:hairdresser).permit(:name, :address, :photo, :location, :description, :photo_cache)
end
My model:
class Hairdresser < ApplicationRecord
belongs_to :user
validates :name, presence: true
validates :location, presence: true
validates :description, presence: true
validates :location, presence: true
mount_uploader :photo, PhotoUploader
end
Hi I actually found an answer to this online. Here is the answer for anyone who has lost time with this issue! :
"If you're on Rails 5, you'll need to update your user association to:
belongs_to :user, optional: true"
I am running a Rails 5.1 app with the following information:
Models
class Company < ApplicationRecord
has_many :complaints
accepts_nested_attributes_for :complaints
validates :name, presence: true
end
class Complaint < ApplicationRecord
belongs_to :company
validates :username, :priority, presence: true
end
Controller
class ComplaintController < ApplicationController
def new
#company = Company.new
#company.complaints.build
end
def create
#company = Company.new(company_params)
respond_to do |format|
if #company.save
format.html { redirect_to complaint_url }
else
format.html { render :new }
end
end
end
private
def company_params
params.require(:company).permit(:name, complaints_attributes: [:username, :priority])
end
Form in view
<%= form_for #company do |f| %>
<%= f.label :name, "Company" %>
<%= f.text_field :name, type: "text" %>
<%= f.fields_for :complaints do |complaint| %>
<%= complaint.label :username, "Username" %>
<%= complaint.text_field :username %>
<%= complaint.label :priority, "Priority" %>
<%= complaint.text_field :priority %>
<% end %>
<%= f.submit 'Submit' %>
<% end %>
If I have just one input field for the complaint_attributes part of the form (in other words just one field for username and one field for priority as shown above), this works just fine.
However, if I want to have multiple fields for username/priority in the form, so that I can submit multiple username/priority combinations in a single submission, I find that submitting the form will only save the last username/priority values from the form. Example of this view would be:
<%= form_for #company do |f| %>
<%= f.label :name, "Company" %>
<%= f.text_field :name, type: "text" %>
<%= f.fields_for :complaints do |complaint| %>
<div>
<%= complaint.label :username, "Username" %>
<%= complaint.text_field :username %>
<%= complaint.label :priority, "Priority" %>
<%= complaint.text_field :priority %>
</div>
<div>
<%= complaint.label :username, "Username" %>
<%= complaint.text_field :username %>
<%= complaint.label :priority, "Priority" %>
<%= complaint.text_field :priority %>
</div>
<% end %>
<%= f.submit 'Submit' %>
<% end %>
I noticed that when submitting the form, I get a hash like this (for submitting single complaint):
{"utf8"=>"✓", "authenticity_token"=>"...", "company"=>{"name"=>"Test", "complaints_attributes"=>{"0"=>{"username"=>"test_person", "priority"=>"1"}}}, "commit"=>"Submit"}
Is there any way to modify the params to make it similar to this and have it saved to the DB?:
{"utf8"=>"✓", "authenticity_token"=>"...", "company"=>{"name"=>"Test", "complaints_attributes"=>{"0"=>{"username"=>"test_person", "priority"=>"1"}"1"=>{"username"=>"test_person", "priority"=>"2"}}}, "commit"=>"Submit"}
Or if not the above, what would be the best way to have the username/priority values saved if using multiple fields for them in a single form?
EDIT: I should point out that I can dynamically add the username/priority field groups as needed, so I don't want to be restricted to a set number.
the second block will override the first fields... you should instead build many complaints in the controller:
def new
#company = Company.new
3.times { #company.complaints.build }
end
and then with the following form it should generate to inputs according to the number of complaints you have built:
<%= form_for #company do |f| %>
<%= f.label :name, "Company" %>
<%= f.text_field :name, type: "text" %>
<%= f.fields_for :complaints do |complaint| %>
<%= complaint.label :username, "Username" %>
<%= complaint.text_field :username %>
<%= complaint.label :priority, "Priority" %>
<%= complaint.text_field :priority %>
<% end %>
<%= f.submit 'Submit' %>
<% end %>
This is the Form. All of the fields get passed (and saved) except the one containing the File.
I have checked that using the
render plain: params[:article].inspect method
giving out this (I have entered the value "n" for all fields):
{"country"=>"n", "region"=>"n", "town"=>"n", "street"=>"n", "company"=>"n", "title"=>"n", "content"=>"n"}
I am leaving out superfluous fields here to make the Form shorter:
<%= form_for(#article, html: { multipart: true }) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :country %>
<%= f.text_field :country, :required => true,
placeholder: "enter country" %>
</div>
<%= f.label :content %>
<%= f.text_field :content, :required => true, placeholder: "town..." %>
</div>
</div>
</div>
</div>
<span class="picture">
<%= form_for #article, html: { multipart: true } do |f| %>
<%= f.text_field :title %>
<%= fields_for :pictures do |ff| %>
<%= ff.file_field :picture %>
<% end %>
<% end %>
</div>
I have also tried the slight variation here, but no change
http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-fields_for
The create method at the Controller is like this:
def create
#article = current_user.articles.build(article_params)
if #article.save
flash[:success] = "Article created!"
redirect_to root_url
else
render 'articles/new'
end
end
and yes, the new method in the Articles controller, is like I was indicated by peers here:
def new
#article = current_user.articles.build
#article.pictures.build
end
The Article Model
class Article < ActiveRecord::Base
belongs_to :user
has_many :pictures
accepts_nested_attributes_for :pictures, allow_destroy: true
And the pictures Model
class Picture < ActiveRecord::Base
belongs_to :article
mount_uploader :picture, PictureUploader
end
Change your <%= fields_for :pictures do |ff| %> to <%= f.fields_for :pictures do |ff| %>
When I create a quote it asks for the quote body, author and user id, user and quotes are associated but I want to show the username of the user with the user ID that someone puts when a quote is create. So if a user has the username "shanks" and his ID is 4 and when user creates a quote and in the text field of user_id he enters 4... I want in the index view of Quotes controller to show the username of the user with that id.
def index
#quote = Quote.new
#quotes = Quote.order(created_at: :desc).all
#user = User.new
end
view:
<!-- form to add a Quote -->
<div class="create-quote">
<%= form_for #quote do |f| %>
<%= f.label :quotetext %><br>
<%= f.text_field :quotetext %><br>
<%= f.label :author %><br>
<%= f.text_field :author %><br>
<%= f.label :user_id %><br>
<%= f.text_field :user_id %><br>
<%= f.submit "Add quote" %>
<% end %>
</div>
<!-- All quotes here -->
<% #quotes.each do |quote| %>
<blockquote>
<p>
<%= quote.quotetext %>
</p>
<footer>
<cite>
<%= quote.author %><br>
</cite>
<p>Posted by: <%= #user.username %> </p> <!-- this -->
<%= link_to "Delete quote", quote_path(quote), method: :delete, data: { confirm: "Are you sure you want to delete this beautiful quote?"} %>
</footer>
</blockquote>
<%= quote.like %></br>
<% end %>
user model:
class User < ActiveRecord::Base
has_many :quotes
validates :username ,presence: true
validates :password ,presence: true
end
quote model:
class Quote < ActiveRecord::Base
belongs_to :user
validates :quotetext, presence: true,
length: { minimum: 5}
validates :author, presence: true
end
your quote is assosiated with user so when you do this it will give you user object
quote.user
Now when you do quote.user.username, it will give user name for the user which is assosiated with the quote.
Use this
<p>Posted by: <%= quote.user.try(:username) %> </p>
I have two models, user and treating (which you can think of as a message).
User:
class User < ActiveRecord::Base
attr_accessible :name, :email, :password, :password_confirmation
has_secure_password
has_many :sent_treatings, :foreign_key => "requestor_id", :class_name => "Treating", dependent: :destroy
has_many :received_treatings, :foreign_key => "requestee_id", :class_name => "Treating", dependent: :destroy
end
Treating:
class Treating < ActiveRecord::Base
attr_accessible :intro, :proposed_date, :proposed_location
validates :intro, presence: true, length: { maximum: 190 }
validates :requestor_id, presence: true
validates :requestee_id, presence: true
belongs_to :requestor, class_name: "User"
belongs_to :requestee, class_name: "User"
default_scope order: 'treatings.created_at DESC'
end
I'm having trouble in my treatings controller setting 'requestee':
class TreatingsController < ApplicationController
before_filter :signed_in_user
def create
requestee = ?
requestor = current_user
#received_treating = requestee.received_treatings.build(params[:treating])
#received_treating.requestor = requestor
if #received_treating.save
flash[:success] = "Treating request sent!"
redirect_to users_path
else
render 'static_pages/home'
end
end
end
The question mark I tried to replace with: User.find(params[:id]), hoping that the user in the current 'users/show' view would be found, but I get this error:
Couldn't find User without an ID
I also tried User.find(params[:treating][:requestee_id]), but this didn't work either. Any ideas?
Thanks!
EDIT:
views/shared/_treating_form.html.erb (this references #received_treating in the users controller, show action):
<div class="field">
<%= f.text_area :intro, placeholder: "Write your introduction here..." %>
</div>
<%= f.submit "Send", class: "btn btn-large btn-primary" %>
EDIT: adding other user profile page:
<% provide(:title, #user.name) %>
<div class="row">
<aside class="span4">
<section>
<h1>
<%= gravatar_for #user %>
<%= #user.name %>
</h1>
</section>
<% if signed_in? %>
<section>
<%= render 'shared/treating_form' %>
</section>
<% end %>
</aside>
<div class="span8">
<% if #user.received_treatings.any? %>
<h3>Treating requests (<%= #user.received_treatings.count %> received)</h3>
<ol class="treatings">
<%= render #received_treatings %>
</ol>
<%= will_paginate #received_treatings %>
<% end %>
</div>
</div>
I think just adding #user.id in a hidden_field would work.
<%= f.hidden_field :requestee_id, :input_html => { :value => #user.id }
<div class="field">
<%= f.text_area :intro, placeholder: "Write your introduction here..." %>
</div>
<%= f.submit "Send", class: "btn btn-large btn-primary" %>
You could also populate the field doing
<%= form_for #user.received_treatings.build do %>
<%= f.hidden_field :requestee_id %>
....
On the controller just do
#received_treating = current_user.sent_treatings.build params[:treating]
I have some doubts if this works but I think it should help you out.