argurments not being passed on edit action, nested objects - html

I'm trying to write an edit action for a my post object which is nested inside the projects one. By the looks of it I'm doing everything as it should be but for some reason when I comes down to load the form, this error message appears "First argument in form cannot contain nil or be empty"
The params being sent are correct "project_id"=>"308", "id"=>"41", however it seems like the form does not know what to do with them.
form
.....
<div class="row">
<div class="col-md-12" id="postform">
<%= form_for ([#project, #post]), html: { multipart: true } do |f| %>
....
view
....
<% if current_user?(post.user) %>
<%= link_to edit_project_post_path(#project, post ) do %>
....
controller
....
before_action :logged_in_user, only: [:create, :edit]
def edit
#project = Project.find(params[:project_id])
#post = #project.posts.find(params[:id])
end
....
post is a nested object of projects and so it has been config on the route s file.
Any ideas what might be causing this problem?
I thought that maybe I need to specify on the form what are these values used for...
Thanks for the help
---- Edit ----
resources :projects do
resources :comments,:posts
end
resources :posts, only: [:create, :destroy, :edit]

form_for is not supposed to work with multipart: true, try removing that or try with form_tag.
Best regards.

Related

Carrierwave multi-file upload Rails 5 not working

In my rails app, I wish for the users to be able to upload multiple files at once.
I am using the carrierwave gem
gem 'carrierwave', github: 'carrierwaveuploader/carrierwave'
On the master branch which supposedly supports the multiple: true
found out in my internet searching desperation about the necessary addition of optional: true in my model for my attachment.
I'm using mysql so I can't use an array type in my database, but I've set up a has_many, belongs_to relationship between Request and Request_Attachment in my database.
my form:
<%= f.fields_for :request_attachments do |ra| %>
<div class="row" id="uploader">
<div class="col-xs-12">
<label class="btn btn-info"> Upload Files
<%= ra.file_field :file, multiple: true, name: "request_attachments[file][]", :style => "display: none" %>
</label>
</div>
</div>
<% end %>
my controller
#request = Request.new(request_params)
if #request.save
if params[:request][:request_attachments]
params[:request][:request_attachments]['file'].each do |f|
#request_attachment = #request.request_attachments.create!(:file => f)
end
end
flash[:success] = "Your request was submitted successfully, check your email for a confirmation message."
redirect_to action: 'index', status: 303
else
render :new
end
def request_params
params.require(:request).permit(:jobtitle, :requester, :status, request_attachments_attributes: [:id, :request_id, :file])
end
my models:
Request:
class Request < ApplicationRecord
has_many :request_attachments
accepts_nested_attributes_for :request_attachments
end
Request_Attachments:
class RequestAttachment < ApplicationRecord
mount_uploader :file, FileUploader
belongs_to :request, optional: true
end
I have tried variations of the form, like taking out the name portion.
When I remove the multiple: true portion, it will work perfectly, but it does not work with the multiple option.
I'm not quite sure where the issue may be, so any help would be great.
What is happening now is that the request gets saved, but
Only 1 request_attachment is created, and
The filename of the request_attachment is nil
Okay, I think I figured it out.
I made a couple changes, which threw an error, and I looked closely at the Parameter Hash, and I noticed essentially it looked like this:
{"utf8"=>"✓",
"request"=>
{"jobtitle"=>"Testing, again and again, and again",
"request_attachments_attributes"=>
{"0"=>
{"file"=>
[#<ActionDispatch::Http::UploadedFile:0x007fee9df806b8
#content_type="image/gif",
#headers="Content-Disposition: form-data; name=\"blah\"; filename=\"logo1.gif\"\r\nContent-Type: image/gif\r\n",
#original_filename="logo1.gif",
#tempfile=blah,
#<ActionDispatch::Http::UploadedFile:0x007fee9df80690
#content_type="image\gif",
#headers=
"Content-Disposition: form-data; name=\"blah\"; filename=\"Blah.gif\"\r\nContent-Type: image/gif\r\n",
#original_filename="Blah.gif",
#tempfile=blahblah]}}
I noticed the "0"=> and thought "wait.... what is that doing there?....
So I removed the name section in my form, and changed my controller to look like this:
if #request.save
params[:request][:request_attachments_attributes]["0"]['file'].each do |f|
#request_attachment = #request.request_attachments.create!(:file => f)
end
And that seemed to have worked.

will_paginate comments partial not rendering?

I was following the instructions on the wiki for this gem:
https://github.com/mislav/will_paginate/wiki
And it works great for my listings controller :/ I was able to get them paginate but I have no idea how to get it work with my comments. My comments controller doesn't have a show method.
class CommentsController < ApplicationController
before_action :authenticate_user!, :except => [:show]
def create
#comment = Comment.new(params[comment_params])
#comment.listing_id = params[:listing_id]
#comment.user_id = current_user.id
#comment.body = params[:comment][:body]
if #comment.save
flash[:success] = "Comment Successful."
redirect_to listing_path(#comment.listing)
else
flash[:alert] = "Comment Failed."
end
end
def destroy
#comment = #listing.comments.find(params[:id])
#comment.destroy
flash[:success] = "Comment Removed."
redirect_to listing_path(#listing)
end
private
def comment_params
params.require(:comment).permit(:user, :body)
end
end
This is the show method I have inside my ListingsController:
def show
#comment = Comment.new
#comment.listing_id = #listing_id
end
It's what sets the comments to my understanding
This is the listings/show.html.erb file's part where it renders the comments:
<div class="commentblock">
<div class="text-left">
<%= render partial: 'comments/form' %>
<%= render partial: 'listings/comment', collection: #listing.comments.reverse %>
</div>
</div>
I know the first part of ruby code actually renders the forms but I don't understand how or what the collection part works or how to apply the pagination to this.
The listings/comment file looks like this:
<div class="panel panel-default">
<div class="panel-heading"><%= comment.user.username %>: <%= time_ago_in_words(comment.created_at)%> ago</div>
<div class="panel-body">
<%= comment.body %>
</div>
</div>
I've tried quite a few things but I still don't really get where or what to change in my code. I went into the listing/comment and tried adding:
<%= will_paginate(comment) %> # this crashed, undefined method `total_pages' for #<Comment:0x007ff556a36468>
EDIT: The will_paginate wiki says you to pass a paginated array when you get the error I got, but I don't know that is done >.>; it doesn't show how you would do that...
EDIT:
http://csnipp.com/s/709 this website said all you had to do was create a file config/initializers/will_paginate.rb and place this line of code in it:
require 'will_paginate/array'
But that didn't help
EDIT:
If you guys need to see more of the code it's actually on github:
https://github.com/ilovemysillybanana/pastie/
I'm really stuck on this D: I followed a tutorial on how to make the comments but theirs didn't paginate.
EDIT:
I fixed it!
The way to do it was by replacing this line:
<%= render partial: 'listings/comment', collection: #listing.comments.reverse %>
with this line:
<%= render partial: 'listings/comment', collection: #list_comments = #listing.comments.paginate(:page => 1, :per_page => 5) %>
But for some reason I don't get the numbers to change the comment pages :/
<%= render partial: 'listings/comment', collection: #listings = #listing.comments.reverse.paginate(:page => params[:page], :per_page => 10) %>
My code was correct, what I wasn't realizing is that #listings or #list_comments was creating a local variable that needed to be paginated itself. I was trying to find a way to paginate either in one command(which if possible I don't care, but if you know how it'd be nice to know for the future I guess) anyway, all that I needed to do to fix this was add this:
<%= will_paginate #listing_comments %>

Error: "Template is missing"

I am getting the error:
Template is missing
Missing template customers/search, application/search with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}.
This is happening when I'm trying to make a search bar to search through my existing customers in the database. I think it's happening because I am using a partial '_search.html.erb' but it needs to be a partial and I don't know how to fix this problem.
Here is my customers\ _search.html.erb:
<%= form_tag search_customers_path do %>
<input class = "searchbar" id ="custsearch" name=query" placeholder = "find colleague" type="text">
<% end %>
the html it's being rendered with (in events\new.html.erb):
<div class = "searchbar">
<%= render partial: 'customers/search', :object => #customers, locals:{} %>
</div>
here is my customers controller 'search' method:
def search
#q = "%#{params[:query]}%"
#customers = Customer.where("first_name LIKE ? or last_name LIKE ? ",#q,#q)
render :layout => false
end
and here is my routes file:
root 'pages#home'
get '/main' => 'pages#main'
get '/signup' => 'customers#new'
resources :customers do
collection do
get 'search'
end
end
get '/compose' => 'events#new'
resources :events
I'm not even sure if this search will work, but this is the first hurdle to achieving it. Please help!
Thanks
Your search action looking for customers/search.html.erb but you don't have any. Try create a new file in customers folder with name search.html.erb and paste your below code there:
<div class = "searchbar">
<%= render partial: 'customers/search', :object => #customers, locals:{} %>
</div>
also remove render :layout => false from your search action. If you are sending request in html format.
#punitcse's answer was right:
def create
# this will be looking for customers/search.html.erb
# you have to explicitly define it:
render partial: "search", layout: false
end
This should resolve the error.
Calling the partial in the view is pretty normal:
<%= render partial: "customers/search", object: #object %>
The issue looks like it's caused by your create action, which can be corrected to resolve it.
You just need to modify you controller to something like
def search
#q = "%#{params[:query]}%"
#customers = Customer.where("first_name LIKE ? or last_name LIKE ? ",#q,#q)
render partial: "customers/search", locals: { customers: #customers }, :layout => false
end
In cutomers/_search change to
#customers/_search.html.erb
<%= form_tag search_customers_path, method: :get do %>
<input class = "searchbar" id ="custsearch" name=query" placeholder = "find colleague" type="text">

Rails POST params not accessed in controller

I'm trying to write an application that will have to interact with POST but I'm having issues accessing the parameters. This is not meant to be useful right now but I'm just trying to flash the result of the form. According to google dev tools, the POST parameter is set to 1.
Here's my routes.rb file
devise_scope :user do
put 'users/toggle_activation' => 'users/sessions#toggle_activation'
get 'users/sign_out' => 'users/sessions#destroy'
post 'pages/home' => 'users/sessions#activities'
end
This is the controller in question
def activities
params.permit(:tennis)
current_user.save
flash[:notice] = params[:tennis]
redirect_to root_path
end
This is the form code
<%= form_for :user do |f| %>
<%= f.check_box :tennis %>
<%= f.submit %>
<% end %>
Any help is appreciated.
If you're using "form_for", then the check_box name will result as "user[tennis]", not just "tennis". View source in your browser and you should see this.
Do something like the following in your controller method (although I'm not sure how it will be called with "form_for :user" because your "activities" route isn't in your routes.rb in the code above):
user_params = params.require(:user).permit(:tennis)
flash[:notice] = user_params[:tennis]

regarding using render in ruby on rails

I am new to rails and still working on fundamentals, so any tips and advice are greatly appreciated!
I've made a functional contact page on a website, and I would like to be able to render the form and functionality of inside a tab on a different page. I have the following code in the static_pages folder in my views folder:
<div id="tabs">
<ul>
<li>About</li>
<li>Contact</li>
</ul>
<div id="tabs-1">
<%= render "shared/about"%>
</div>
<div id="tabs-5">
<%= render "contact/new"%>
</div>
where <%= render "contact/new"%> corresponds to the new.html.erb file in contact in views.
the relevant code inside my routes.rb is
match 'contact' => 'contact#new', :as => 'contact', :via => :get
match 'contact' => 'contact#create', :as => 'contact', :via => :post
and here is my controller:
class ContactController < ApplicationController
def new
#message = Message.new
end
def create
#message = Message.new(params[:message])
if #message.valid?
NotificationsMailer.contact_pr(#message).deliver
redirect_to(root_path, :notice => "Message was successfully sent.")
else
flash.now.alert = "Please fill all fields."
render :new
end
end
end
However, It seems that whatever I try I still am unable to render the form. I apologize if this is a very simple question, and I am mostly interested in getting better at fundamentals in Ruby on Rails so any advice is appreciated! Thanks!
If you want to render this form in other templates (and you do), you should extract it to partial named for example: _form.html.erb.
Then, you should put
<%= render 'contact/form' %>
everywhere you need this partial in view (including new.html.erb template).
When you are done with this, you should leave
render :new
in controller, as it works a little bit different than in view and it renders appropriate action template instead of partial.
Of course, you need to set #message variable everywhere you need this partial. Or, you can put in your partial:
<%= form_for(#message || Message.new) do |f| %>
More info about layouts and rendering here.