partial form not creating new value RoR - ruby-on-rails

I am new to Ruby on Rails. My Question might sound weird, but i am stuck. i have a form Create that is on html page. i used render partial, but this form is not creating any value. here is my controller code.
Controller.rb
before_filter :signed_in_user, only: [:create, :destroy]
def create
#suppliers = current_user.suppliers.build(params[:supplier_name])
if #suppliers.save
flash[:success] = "Supplier Saved!"
redirect_to 'suppliers/home'
else
render 'suppliers/home'
end
end
def destroy
end
def home
if signed_in?
#supplier = current_user.suppliers.build
#feed_items = current_user.feed.paginate(page: params[:page])
end
end
my home.html.erb
<div class="row">
<aside class="span4">
<section>
<%= render 'suppliers/suppliers_form' %>
</section>
</aside>
<div class="span8">
<h3>Micropost Feed</h3>
<%= render 'suppliers/feed_supplier' %>
</div>
</div>
My _supplier_form.html.erb is
<%= form_for(#supplier) do |f| %>
<div>
<%= f.text_field :supplier_name, placeholder: "Add new Supplier" %>
</div>
<%= f.submit "Add", class: "btn btn-large btn-primary" %>
<% end %>
My _feed_supplier.html.erb is
<% if #feed_items.any? %>
<ol class="microposts">
<%= render partial: 'suppliers/feed_item', collection: #feed_items %>
</ol>
<%= will_paginate #feed_items %>
<% end %>
my _feed_item.html.erb is
<li id="<%= feed_item.id %>">
<span class="user">
<%= link_to feed_item.user.name, feed_item.user %>
</span>
<span class="content"><%= feed_item.supplier_name %></span>
</li>
please guide me to right direction, and if anything else is required then do ask. Thanks in advance
Note: all the mentioned files are in same folder i.e. suppliers. except the controller file

form_for #supplier
will create a parameter hash like
{ :supplier => { :supplier_name => '[some value you put in your form]' }}
so the create action should use
#suppliers = current_user.suppliers.build(params[:supplier])
There is no params[:supplier_name].

I think for the partials, you don't need to write suppliers/*, for example:
<%= render 'suppliers/suppliers_form' %>
could just be
<%= render 'suppliers_form' %>
not sure why that would be causing your app to do what it's doing, but worth a try!

Related

Paginating users with a follow/unfollow button: Ajax runs into problems because of duplicate class names

My users/show.html.erb pages work correctly because there is only one class name displayed on each page. When users are paginated in users/index.html.erb along with follow/unfollow buttons the relationship/js.create.erb and relationship/js.destroy.erb get wacky because there are duplicate class names on the page, (the first paginated user updates regardless of which user is followed/unfollowed and this only fixes itself when the page is refreshed (the actual model still works correctly)).
I did not use the unfollow/follow partials in users/index.html.erb because there is no #user variable in index.html.erb, it paginates #users, so I use user.id.
class RelationshipsController < ApplicationController
before_action :logged_in_user
def create
#user = User.find(params[:followed_id])
current_user.follow(#user)
respond_to do |format|
format.html { redirect_to #user }
format.js
end
end
def destroy
#user = Relationship.find(params[:id]).followed
current_user.unfollow(#user)
respond_to do |format|
format.html { redirect_to #user }
format.js
end
end
end
**relationships/create.js.erb**
$("#follow_form").html("<%= escape_javascript(render('users/unfollow')) %>");
$("#followers").html('<%= #user.followers.count %> <br> followers');
**relationships/destroy.js.erb**
$("#follow_form").html("<%= escape_javascript(render('users/follow')) %>");
$("#followers").html('<%= #user.followers.count %> <br> followers');
**users/index.html.erb**
<div class="row community">
<% #users.in_groups_of(3, false).each do |users| %>
<div class="col-sm-12">
<% users.each do |user| %>
<ul class="name-head">
<% unless current_user == user %>
<div id="follow_form">
<% if current_user.following?(user) %>
<%= form_for(current_user.active_relationships.find_by(followed_id: user.id),
html: { method: :delete }, remote: true) do |f| %>
<%= f.submit "Unfollow", class: "btn btn-primary" %>
<% end %>
<% else %>
<%= form_for(current_user.active_relationships.build, remote: true) do |f| %>
<div><%= hidden_field_tag :followed_id, user.id %></div>
<%= f.submit "Follow", class: "btn btn-primary" %>
<% end %>
<% end %>
</div>
<% end %>
</ul>
<div class="col-xs-12">
<div class="col-xs-4">
<a href="<%= following_user_path(user.id) %>">
<center><strong id="following" class:"stat">
<%= user.following.count %><br>
following
</strong></center>
</a>
</div>
<div class="col-xs-4">
<a href="<%= followers_user_path(user.id) %>">
<center><strong id="followers" class="stat">
<%= user.followers.count %><br>
followers
</strong></center>
</a>
</div>
<div class="col-xs-4">
<center><strong id="photo-count" class="stat">
<%= user.photos.count %><br>
photos shared
</strong></center>
</div>
</div>
</div>
<% end %>
</div>
<% end %>
</div>
<%= will_paginate %>
**users/show.html.erb**
.
.
.
<li class="follow">
<%= render 'follow_form' if logged_in? %>
</li>
</ul>
</div>
<div class="col-xs-12">
<div class="col-xs-4">
<a href="<%= following_user_path(#user) %>">
<center><strong id="following" class:"stat">
<%= #user.following.count %><br>
following
</strong></center>
</a>
</div>
<div class="col-xs-4">
<a href="<%= followers_user_path(#user) %>">
<center><strong id="followers" class="stat">
<%= #user.followers.count %><br>
followers
</strong></center>
</a>
</div>
<div class="col-xs-4">
<center><strong id="photo-count" class="stat">
<%= #user.photos.count %><br>
photos shared
</strong></center>
</div>
end
**_follow_form.html.erb**
<% unless current_user?(#user) %>
<div id="follow_form">
<% if current_user.following?(#user) %>
<%= render 'unfollow' %>
<% else %>
<%= render 'follow' %>
<% end %>
</div>
<% end %>
**_follow.html.erb**
<%= form_for(current_user.active_relationships.build, remote: true) do |f| %>
<div><%= hidden_field_tag :followed_id, #user.id %></div>
<%= f.submit "Follow", class: "btn btn-primary" %>
<% end %>
**_unfollow.html.erb**
<%= form_for(current_user.active_relationships.find_by(followed_id: #user.id),
html: { method: :delete },
remote: true) do |f| %>
<%= f.submit "Unfollow", class: "btn btn-primary" %>
<% end %>
Edit: I thought about passing the user_id into the classes, such as:
<div id="follow_form<%="#{user.id}"%>">
which created <div id="follow3">
However I do not know how I can pass this into the destroy.js.erb and create.js.erb
I have tried many combinations such as:
$("#follow_form<%="#{user.id}"%>").html("<%= escape_javascript(render('users/unfollow')) %>");
and
$("#follow_form<%= #user.id%>").html("<%= escape_javascript(render('users/unfollow')) %>");
however, the code is still does not work and even if it did, it would still need work because changing the create/destroy.js.erb files would break the users/show.html.erb follow/unfollow buttons.
EDIT: I have also found this question which is similar but it does not contain an accepted answer.
Edit for Heroku Logs: This is what I get when I follow/unfollow a user on my users/index.html.erb page:
Started DELETE "/relationships/360" for 184.90.97.154 at 2016-05-13 20:05:17 +0000
Processing by RelationshipsController#destroy as JS
Rendered users/_follow.html.erb (1.6ms)
(1.1ms)[0m [1mSELECT COUNT(*) FROM "users" INNER JOIN "relationships" ON "users"."id" = "relationships"."follower_id" WHERE "relationships"."followed_id" = $1[0m [["followed_id", 1]]
Started POST "/relationships" for 184.90.97.154 at 2016-05-13 20:07:26 +0000
Processing by RelationshipsController#create as JS
[1m[36m (1.5ms)[0m [1mCOMMIT[0m
I've duplicated your code and, after adding the modifications below, it worked perfectly. (i.e. I don't need a page reload for the "Follow/Unfollow" button to change)
Try the following to see if it works:
users/index.html.erb (only the relevant code here, which is the "Follow/"Unfollow" button)
<ul class="name-head">
<% unless current_user == user %>
<%= render partial: 'follow_form', locals: { user: user } %>
<% end %>
</ul>
users/_follow_form.html.erb
<div id="follow_form-<%= user.id %>">
<% if current_user.following?(user) %>
<%= render partial: 'unfollow', locals: { user: user } %>
<% else %>
<%= render partial: 'follow', locals: { user: user } %>
<% end %>
</div>
users/_unfollow.html.erb
<%= form_for(current_user.active_relationships.find_by(followed_id: user.id), html: { method: :delete }, remote: true) do |f| %>
<%= f.submit "Unfollow", class: "btn-default" %>
<% end %>
users/_follow.html.erb
<%= form_for(current_user.active_relationships.build, remote: true) do |f| %>
<div><%= hidden_field_tag :followed_id, user.id %></div>
<%= f.submit "Follow", class: "btn" %>
<% end %>
relationships/create.js.erb
$("#follow_form-<%= #user.id %>").html("<%= escape_javascript(render(partial: 'users/unfollow', locals: { user: #user })) %>");
relationships/destroy.js.erb
$("#follow_form-<%= #user.id %>").html("<%= escape_javascript(render(partial: 'users/follow', locals: { user: #user })) %>");
Note the use of <%= render partial: "_partial.html.erb", locals: { var_name: var } %>. the optional hash locals: { ....... } allows you to pass in a local variable to a partial you want to render (_partial.html.erb) In this case, you also need to add partial: before the name of the partial you want to render.
This way, your user local variable will become available not only in users/index.html.erb, but also in other files listed above.
The problem is in your relationship/js.create.erb and relationship/js.destroy.erb partials, because with your code you only update the first #follow-form div in your page (that is the #follow-form for first user, as you are reporting).
You should change your users\index.html.erb to
<% unless current_user == user %>
<div id="follow-form-<%= user.id %>">
This way, every user will have its unique div element. Then, just modify relationship/js.create.erb as follows:
$("#follow-form-<%= #user.id %>").html("<%= escape_javascript(render('users/unfollow')) %>");
$("#followers").html('<%= #user.followers.count %> <br> followers');
and relationship/js.destroy.erb accordingly, then you should have everything working as expected.

Error: param is missing or the value is empty:retweet

I am new to Rails. I want to pass parameters to DB via controller, but I receive this error param is missing or the value is empty:retweet. I think the problem is the way of passing parameters in view.
Here is the view
<% for #p in #posts %>
<div class="panel panel-default post-panel">
<div class="panel-body row">
<div class="col-sm-1">
<img src="/avatar.png" class="rounded-img" height="50px" width="50px">
</div>
<div class="col-sm-11">
<p class="post-title"><%= User.find(#p.user_id).username %> <span class="post-creation">- <%= #p.created_at.to_formatted_s(:short) %></span></p>
<p class="post-content"><%= #p.content %></p>
</div>
<div class="col-sm-12">
<p class="post-links">
<span class="glyphicon glyphicon-comment g-links" aria-hidden="true"></span>
**<%= form_for Retweet.new do |f| %>
<%= hidden_field_tag current_user.id, (:user_id) %>
<%= hidden_field_tag #p.id, (:post_id) %>
<%= f.submit "Retweet", class:"btn btn-primary"%>**
<% end %>
And here is the Controller
def new
#retweet = Retweet.new
end
def create
#retweet = Retweet.new(post_params)
redirect_to(:back)
end
private def post_params
params.require(:retweet).permit(:user_id, :post_id)
end
end
You should read up some tutorials on basic REST controllers in Rails. Your create action didn't save the retweet.
def create
#retweet = Retweet.new(post_params)
if #retweet.save
redirect_to(:back)
else
render action: 'new'
end
end
Edit: Just noticed your form is all wrong:
<%= form_for Retweet.new do |f| %>
<%= f.hidden_field :user_id, current_user.id %>
<%= f.hidden_field :post_id, #p.id %>
<%= f.submit "Retweet", class:"btn btn-primary"%>**
<% end %>
Mind you that you shouldn't allow settign the user_id like this, it is very easy to change it and thus mess around with your data. Instead you should add this to retweet#create:
#retweet.user = current_user

Rails: Two different NoMethodError's when trying to display files

I'm making a basic application and I made it so a user can attach a file to a form post. That all works perfectly fine, but now I'm trying to display a link to the file and it doesn't seem to work.
I'm getting two errors. One if I attach a file and another if I don't attach a file. They both say undefined method 'doc=' for nil:NilClass but are on different lines of code.
If I don't upload a file this is what I get: NoMethodError in Projects#index on this line of code <% if #project.doc %>.
If I do upload a file this is what I get: NoMethodError in ProjectsController#create on this line of code #project.doc = uploaded_io.original_filename
projects_controller.rb
class ProjectsController < ApplicationController
def index
#projects = Project.all
end
def show
end
def new
#projects = Project.new
end
def create #no view
#projects = Project.new(project_params)
uploaded_io = params[:doc]
if uploaded_io.present?
File.open(Rails.root.join('public', 'uploads', uploaded_io.original_filename), 'wb') do |file|
file.write(uploaded_io.read)
#project.doc = uploaded_io.original_filename
end
end
if #projects.save
redirect_to projects_path, :notice => "Your project was sent!"
else
render "new"
end
end
def edit
#projects = Project.find(params[:id])
end
def update #no view
#projects = Project.find(params[:id])
if #projects.update_attributes(project_params)
redirect_to projects_path, :notice => "Your project has been updated."
else
render "edit"
end
end
def destroy #no view
#projects = Project.find(params[:id])
#projects.destroy
redirect_to projects_path, :notice => "Your project has been deleted."
end
private
def project_params
params.require(:project).permit(:title, :description)
end
end
index.html.erb
<div class="container">
<div class="page-header">
<h1>Projects<small> Here are all of your projects.</small></h1>
</div>
</div>
<% #projects.each do |project| %>
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">
<%= project.title %>
</div>
</div>
<div class="panel-body">
<p>
<%= project.description %>
</p>
<br>
<%= link_to "Discuss", new_project_discussion_path(project) %> |
<%= link_to "Tasks", new_project_task_path(project) %> |
<%= link_to "Edit", edit_project_path(project) %> |
<%= link_to "Delete", project, :method => :delete %>
<% if #project.doc %>
<p>Document: <%= link_to #project.doc, "/uploads/#{#project.doc}", :target => "_blank" %></p>
<% end %>
</div>
</div>
<%end%>
<br>
<br>
<div class="container">
<p><a class="btn btn-primary btn-lg" href="/projects/new" role="button">Create project</a></p>
</div>
_form.html.erb
<%= form_for(#projects, :html => { :multipart => true}) do |f| %>
<% if #projects.errors.any? %>
<ul>
<% #projects.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
<% end %>
<div class="container">
<div class="form-group">
<%= f.label :title %>
<%= f.text_field :title, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :description %>
<%= f.text_area :description, class: "form-control" %>
</div>
<%= label_tag :doc, 'Files (optional)' %>
<%= file_field_tag :doc %>
<br>
<div class="form-group">
<%= f.submit "Submit Project", class: "btn btn-primary" %>
</div>
<% end %>
Updated :
You have many errors, here are a few that I found :
uploaded_io = params[:doc]
Should be
uploaded_io = params[:project][:doc]
Also delete this line
#project.doc = uploaded_io.original_filename
You don't need that.
Finally, in your views, you should have project.doc instead of #project.doc

form_for on commentables in rails

I'm having problems with the "First argument in form cannot contain nil or be empty" error that I haven't been able to find an answer for.
Basically, I have Posts, which show up on a User's show page, which should each have the option to comment on them. My routes are as follows:
resources :posts, only: [:create, :destroy] do
resources :comments, only: [:create, :destroy]
end
users/show.html.erb
<ol class="posts">
<%= render #posts %>
</ol>
posts/_post.html.erb
<li>
<span class="content"><%= post.content %></span>
<span class="timestamp">
Posted <%= time_ago_in_words(post.created_at) %> ago.
</span>
<% if current_user?(post.user) %>
<%= link_to "delete", post, method: :delete,
data: { confirm: "You sure?" },
title: post.content %>
<% end %>
<span class="content">
<ul> Comments: <%= post.comments.count %></ul>
<% post.comments.each do |comment| %>
<ul> <%= comment.comment %> </ul>
<% end %>
</span>
<% if post != nil %>
<% form_for [post, #comment] do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_area :content, placeholder: "Comment..." %>
</div>
<%= f.submit "Post", class: "btn btn-lg btn-primary" %>
<% end %>
<% end %>
</li>
s comments_controller.rb
def create
#post = Post.find(params[:id])
#comment = #post.comments.build(comment_params)
#comment.user = current_user
if #comment.save
flash[:success] = "Posted!"
redirect_to #post
else
render 'static_pages/home'
end
end
def destroy
#comment.destroy
redirect_to root_url
end
Showing C:/app/views/posts/_post.html.erb where line #21 raised: (line 21 is the form_for line)
First argument in form cannot contain nil or be empty
app/views/posts/_post.html.erb:21:in _app_views_posts__post_html_erb___306000501_37434348'
app/views/users/show.html.erb:19:in_app_views_users_show_html_erb__480533737_37130988'
If each post had a show page, I know that I would put #posts on the show action and then make it an instance variable, but since the each post needs a separate comment dialogue box, I can't make it that general. It doesn't go through the posts controller though so I can't make it specific to each post. I'm using acts_as_commentable for the comments. Ideally, I would like to make them generic and put all the form_for comment stuff into a partial, but I'll figure that out later.

Create a link from a div - Ruby on Rails

Currently I have a text link within the div that links correctly <%= link_to 'Show', profile %>. I have read that the below is the proper way to turn a div into a link
<%= link_to root_path do %>
<div>Hey!</div>
<% end %>
Though when I apply that to my block it gives me a undefined local variable or method 'profile'
<%= link_to profile do %>
<div id="profiles" class="transitions-enabled">
<% #profiles.each do |profile| %>
<div class="box panel panel-default">
<div class="panel-body">
<%= image_tag profile.image.url(:medium) %>
<%= profile.artist %><br/>
<%= link_to 'Show', profile %>
</div>
</div>
<% end %>
</div>
<% end %>
My original block without the attempt at linking:
<div id="profiles" class="transitions-enabled">
<% #profiles.each do |profile| %>
<div class="box panel panel-default">
<div class="panel-body">
<%= image_tag profile.image.url(:medium) %>
<%= profile.artist %><br/>
<%= link_to 'Show', profile %>
</div>
</div>
<% end %>
</div>
My Controller:
class ProfilesController < ApplicationController
before_action :set_profile, only: [:show, :edit, :update, :destroy, :id]
# GET /profiles
# GET /profiles.json
def index
#profiles = Profile.all
end
# GET /profiles/1
# GET /profiles/1.json
def show
end
# GET /profiles/new
def new
#profile = Profile.new
end
#...
Your first example is problematic in many ways - you have links inside links. I'm not exactly sure what you're looking to output from this - but basically you need the
<%= link_to root_path do %>
<div>Hey!</div>
<% end %>
behavior to replace where you have <%= link_to 'Show', profile %>
Something along the lines of:
<div id="profiles" class="transitions-enabled">
<% #profiles.each do |profile| %>
<div class="box panel panel-default">
<div class="panel-body">
<%= image_tag profile.image.url(:medium) %>
<%= profile.artist %><br/>
<%= link_to profile do %>
<div>
fancy pants stuff here
</div>
<% end %>
</div>
</div>
<% end %>
</div>
If you can give me some guidance on what you want in the div I can post you some code to achieve that, I'm just not clear on what you are looking for exactly.
Another example could be (if you wanted more of the pieces to fall inside that <div></div>:
<div id="profiles" class="transitions-enabled">
<% #profiles.each do |profile| %>
<div class="box panel panel-default">
<div class="panel-body">
<%= link_to profile do %>
<div>
<%= image_tag profile.image.url(:medium) %>
<%= profile.artist %><br/>
... more fancy pants stuff here ...
</div>
<% end %>
</div>
</div>
<% end %>
</div>

Resources