I am new to Rails, can you check my code to see where I might be going wrong. I am attempting to create a Song object.
By looking at my SQLite File, I can see that no new songs are being created.
In views/songs/new.html.erb
<!DOCTYPE html>
<html>
<head>
<title>MusicDiscoveryApp</title>
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
</head>
<body>
<%= form_for(#song, :html => {:id => 'add-to-library', :method => :post}) do |f| %>
<div class="item-info">
<%= f.select :category_id, [['Pop', 1], ['Rock', 2], ['Rap', 3], ['Reggae', 4], ['Other', 5]] , {:prompt=>"Select A Category"}, :id=>"choose-category"%>
</div>
<div class="item-info">
<%= f.text_field :name , :placeholder=>"Song Name"%>
</div>
<div class="item-info">
<%= f.text_field :price, :placeholder=>"Price"%>
</div>
<div class="item-info">
<%= f.text_area :details ,:placeholder=>"Details"%>
</div>
<div class="item-actions">
<%= f.submit "Post to Songs Library", :class=>"add-song"%>
</div>
<% end %>
</body>
</html>
The 'new' method from songs_controller.rb - it was automatically generated
def new
#song = Song.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #song }
end
end
The 'create' method from songs_controller.rb - also automatically generated
def create
#song = Song.new(params[:song])
end
Thanks for your time, I hope you can explain to me what I did wrong here. Thanks once again.
The song isn't being saved. Add:
#song = Song.new(params[:song])
#song.save
to your controller create method or change new to create
#song = Song.create(params[:song])
Related
I am new to Rails. I am developing a web application where a user inserts inventory of shoes. So the user enters style code, size, price, and quantity. I want quantity to define how many entries there are in the database. So, if the quantity is three, three separate rows would be created for each shoe. Currently each form submission creates one row in the database.
My create in my shoe_controller:
def create
#shoe = Shoe.new(shoe_params)
respond_to do |format|
if #shoe.save
format.html { redirect_to #shoe, notice: 'Shoe was successfully created.' }
format.json { render :show, status: :created, location: #shoe }
else
format.html { render :new }
format.json { render json: #shoe.errors, status: :unprocessable_entity }
end
end
end
My _form.html.erb
<%= form_with(model: shoe, local: true) do |form| %>
<% if shoe.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(shoe.errors.count, "error") %> prohibited this shoe from being saved:</h2>
<ul>
<% shoe.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :sku %>
<%= form.text_field :sku %>
</div>
<div class="field">
<%= form.label :size %>
<%= form.text_field :size %>
</div>
<div class="field">
<%= form.label :quantity %>
<%= form.number_field :quantity %>
</div>
<div class="field">
<%= form.label :price %>
<%= form.text_field :price %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
What changes would I need to make to achieve the result I am looking for?
Thanks!
#rohit is correct in that using the Shoe.create method will get you what you want. But to implement this, you can change your controller to the following. I'm sure there are much cleaner ways of doing this, but it should get you what you're looking for. Also, I would suggest validating the quantity in shoe_params is a positive integer.
def create
#show = Show.new(shoe_params)
# This will create an array of shoes from your params
new_shoes = (1..shoe_params[:quantity]).collect { Shoe.new(shoe_params) }
# Save each record and put the result in an array
success = new_shoes.map(&:save)
if success.all?
# all records saved
else
# maybe #shoe.valid? is false or something else happened
end
end
you can use ActiveRecord::Persistence#create, which can accept an array of hashes as a parameter.
Suppose quantity is three, so build the 3 new hash which will contain your records.
shoes_params = [
{
code: 1,
size: 8,
price: 300,
quantity: 1
},
{
code: 1,
size: 8,
price: 300,
quantity: 1
}, ...
]
Shoe.create(shoes_params)
Yes, I already checked here. It didn't work.
Rails: 5.0.2
Ruby: 2.4.0
I have a collection for comments and every time it is called, it renders one time too many and an empty comment always appears below others and when no comments exist, one empty one still renders.
Here is the code:
View
<h2>Add a comment:</h2>
<%= render 'comments/form' %>
<h2>Comments</h2>
<%= render #video.comments || "There are no comments yet." %>
Form partial
<%= form_for([#video, #video.comments.new]) do |f| %>
<p>
<%= f.label :name %><br>
<%= f.text_field :commenter %>
</p>
<p>
<%= f.label :body %><br>
<%= f.text_area :body %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
Comment partial
<p>
<strong>Name:</strong>
<%= comment.commenter %>
</p>
<p>
<strong>Comment:</strong>
<%= comment.body %>
</p>
<p>
<%= link_to 'Destroy Comment', [comment.video, comment],
method: :delete,
data: { confirm: 'Are you sure?' } %>
</p>
Controller
def create
#video = Video.find(params[:video_id])
#comment = #video.comments.create(comment_params)
redirect_to video_path(#video)
end
def destroy
#video = Video.find(params[:video_id])
#comment = #video.comments.find(params[:id])
#comment.destroy
redirect_to video_path(#video)
end
private
def comment_params
params.require(:comment).permit(:commenter, :body)
end
Does anyone know why this would render the partial an extra time?
You may try to call .scope on comments association:
<%= render #video.comments.scope || "There are no comments yet." %>
I have a scaffold generated index.html.erb and am wondering if it is okay that is does not have basic HTML structure?
This is my code:
<% provide(:title, "Signing Up") %>
<h1>Signing Up</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(:reader, url: readers_path) do |f| %>
<%= f.label :email %><br>
<%= f.email_field :email, class: 'form-control' %>
</p>
<p>
<%= f.label :password %><br>
<%= f.password_field :password_digest, class: 'form-control' %>
</p>
<%= f.submit "Signing Up", class: "btn btn-primary" %>
<% end %>
</div>
</div>
I don't see usual HTML, <body>, <head> tags etc. Can I add it or is it not necessary?
It isn't necessary. In Rails, you have an application.html.erb file under views/layouts. This is used as a default for rendering any page.
This file is where you will see the usual HTML structure (DOCTYPE, head, body etc).
To find the base layout, Rails will look for a file in app/views/layouts with the same base name as the controller.
For example, rendering actions from the PostsController class will use app/views/layouts/posts.html.erb.
If there is no such controller-specific layout, Rails will use app/views/layouts/application.html.erb which is what is happening when you generate the scaffold.
This is what the application.html.erb looks like generally on a fresh project:
<!DOCTYPE html>
<html>
<head>
<title></title>
<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
<%= csrf_meta_tags %>
</head>
<body>
<%= yield %> #Content from the views is shown
</body>
</html>
See the docs for more information
I'm using Carrierwave with Rails to upload and display images. I've been using it for articles and other parts of my site without a problem but for some reason it's not working for the model I just created. I can see the space for the image tag rendered without the image and then disappear quickly when the page loads. Nothing like this has occurred until I tried it with this model which isn't much different from my other models:
class Ad < ActiveRecord::Base
validates_numericality_of :zip_code
validates_presence_of :image, :advertiser
mount_uploader :image, ImageUploader
end
My create and index actions:
def create
#ad = Ad.new(params[:ad].permit(:image, :advertiser, :zip_code))
if #ad.save
redirect_to :back
else
flash[:error] = "Invalid input"
redirect_to :back
end
end
def index
#new_ad = Ad.new
#ads = Ad.all.reverse
end
My _new partial:
<div id="card">
<%= form_for #new_ad, html: {multipart: true, "data-ajax" => false} do |f| %>
<p>
<%= f.file_field :image %>
</p>
<p>
<%= f.text_field :advertiser, placeholder: "Advertiser" %>
</p>
<p>
<%= f.text_field :zip_code, placeholder: "Zip code" %>
</p>
<p>
<%= f.submit "Upload" %>
</p>
<% end %>
</div></br>
My index view:
<%= render "new" %>
<% for ad in #ads %>
<div id="card">
<div align="center">
<%= image_tag ad.image %>
<%= ad.advertiser %>
<%= ad.zip_code %>
</div>
</div></br>
<% end %>
As per my understanding problem is with your index view.
<%= image_tag ad.image %>
you are using ad.image this will return you imageuploader object not image path. So instead of using ad.image you can use ad.image.url(relative path) or ad.image.current_path(absolute path)
<%= image_tag ad.image.url %>
I have a nested form.
Right now I want to arrange the layout with some CSS but I am facing trouble allocating dom ids to the form.
This is the subject controller.
I want to allocate lesson_type as seen in line 5 as the dom id.
1 def index
2 #subjects = Subject.all
3 #subject = Subject.new
4 lecture = #subject.lessons.build
5 lecture.lesson_type = "lecture"
lecture.lesson_groups.build
lecture.destroy
tutorial = #subject.lessons.build
tutorial.lesson_type = "tutorial"
tutorial.lesson_groups.build
tutorial.destroy
laboratory = #subject.lessons.build
laboratory.lesson_type = "laboratory"
laboratory.lesson_groups.build
laboratory.destroy
respond_to do |format|
format.html # index.html.erb
format.json { render json: #subjects }
format.js
end
end
The following is the form.
<%= nested_form_for(#subject, :remote=>true) do |f| %>
<% if #subject.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#subject.errors.count, "error") %> prohibited this subject from being saved:</h2>
<ul>
<% #subject.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :subject_code %><br />
<%= f.text_field :subject_code %>
</div>
<%= f.fields_for :lessons do |lesson| %>
<%= lesson.label :lesson_type %><br/>
<%= lesson.text_field :lesson_type, :readonly=>true%><br/>
<%= lesson.label :name %><br/>
<%= lesson.text_field :name %><br/>
<%= lesson.fields_for :lesson_groups do |lesson_group| %>
<%= lesson_group.label :group_index %><br/>
<%= lesson_group.text_field :group_index %>
<%= lesson_group.link_to_remove "Remove this task" %>
<% end %>
This is the div where I want to add an id to.
<%= f.fields_for :lessons do |lesson| %>
<%= lesson.label :lesson_type %><br/>
<%= lesson.text_field :lesson_type, :readonly=>true%><br/>
<%= lesson.label :name %><br/>
<%= lesson.text_field :name %><br/>
I have tried out the following but it did not worked.
<div id = "<%= :lesson_type%>">
Would appreciate it if someone could help me out thanks.
sorry..
#controller
def index
...
lecture.lesson_type = #lesson_dom_id = "lecture" # line 5
...
end
#view
<div id="<%= #lesson_dom_id %>">