In routes.rb, I used resources nicknames. In nickname_controller, I did:
def index
#nick_name = current_user.nicknames.build
#nick_names = current_user.nicknames.all
end
def create
#nick_name = current_user.nicknames.build(nn_create_param)
if #nick_name.save
flash[:success]= 'Name created'
redirect_to nickname_path
else
flash[:danger]= "Name can't be created"
redirect_to nickname_path
end
end
In index view file,
<%= form_for #nick_name do |f| %>
<%= f.text_field :nickname %>
<%= f.submit 'Submit' %>
<% end %>
When I submit the form, it says uninitialized constant NicknamesController.
Can anyone tell me where the problem is?
The Controller name has to be pluralized.
nicknames_controller.rb
class NicknamesController < ApplicationController
Your controller file name should be nicknames_controller.rb not nickname_controller.rb. And your controller class name should be NicknamesController and not NicknameController.
Related
im making a twitter clone and trying to make it so the users username appears next to their tweet.
Ive made it work through adding a user and a tweet in the seed file, hoever when i add a create,new method and a form it comes up with the error "Couldn't find User without an ID" and highlighting the first line of my create method. not sure what the issue is, thanks.
class TweetsController < ApplicationController
before_action :authenticate_user!, :except => [:index, :new, :create]
def index
#tweets = Tweet.all.order("created_at DESC")
#tweet = Tweet.new
end
def show
#tweet = Tweet.find(params[:id])
end
def new
# #tweet = Tweet.new
end
def create
#user = User.find(params[:id])
#tweet = Tweet.new(tweet_params)
#tweet.user = #user
if #tweet.save
redirect_to tweets_path
end
end
def edit
#tweet = Tweet.find(params[:id])
end
def update
#tweet = Tweet.find(params[:id])
#tweet.update(tweet_params)
redirect_to tweets_path
end
private
def tweet_params
params.require(:tweet).permit(:user_id,:content)
end
end
<h1>TWEETS</h1>
<%= simple_form_for [#user,#tweet], id: "form-submit" do |f| %>
<%= f.input :content, label: "Tweet" %>
<%= f.input :user %>
<%= f.button :submit, class: "btn btn-danger" %>
<% end %>
<br>
<% #tweets.each do |tweet| %>
<ul>
<li>
<%= tweet.created_at.strftime("%B %d %Y, %l:%M%P") %> <br>
<%= tweet.content %>
<%= tweet.user.username %>
</li>
</ul>
<% end %>
You need to define #user in a variable in your index method.
Any variable you use in the form needs to be declared somewhere, either in the helper, controller, or view. Rails convention is to declare them in the controller normally.
I would need to see your config/routes.rb file for the error message you are getting in the image, but if you type rails routes at the command line, you can see a list of all available routes, when you use:
simple_form_for [#user, #tweet]
Rails will interpret [#user, #tweet] as user_tweets_path, and try to submit the form to this path. That path is defined in your config/routes.rb file.
The error is telling you that you have not defined this path in the routes file. To define this path you can add this line to your routes file:
resources :users do
resources :tweets
end
I'm just starting to learn Rails so please forgive the dumb question. In my web app, I was able to set up working models, forms, and view. A user is able to input their decimal answer and it shows on the web page perfectly. However, I want to subtract one user input from another user input. So if the user inputs 100 in one model "post.price" and 10 in another input model "ratings1.content" > I want it to show 90 in the "fprice.content3". Any help that you guys can give me would be so amazing, I feel like the issue might be in my controller for fprice. I have listed below all my relevant code. Thank you again :)
_form.html "post.price"
<%= simple_form_for #post do |f| %>
<%= f.input :title %>
<%= f.input :image %>
<%= f.input :price %>
<%= f.button :submit %>
<% end %>
_form.html "ratings1s.content"
<%= simple_form_for ([#post, #post.ratings1s.build]) do |f| %>
<%= f.input_field :content %>
<% end %>
_form.html "fprice.content3"
<%= simple_form_for ([#post, #post.fprices.build]) do |f| %>
<%= f.input_field :content3 %>
<% end %>
Rails Controller "fprices"
class FpricesController < ApplicationController
before_action :authenticate_user!
def create
#post = Post.find(params[:post_id])
#fprice = Fprice.create(params[:fprice].permit(:content3))
#fprice.content3 === #post.price - #ratings1.content
#fprice.user_id = current_user.id
#fprice.post_id = #post.id
if #fprice.save
redirect_to post_path(#post)
else
render 'new'
end
end
end
Rails Controller "ratings1s"
class Ratings1sController < ApplicationController
before_action :authenticate_user!
def create
#post = Post.find(params[:post_id])
#ratings1 = Ratings1.create(params[:ratings1].permit(:content))
#ratings1.content *= 10
#ratings1.user_id = current_user.id
#ratings1.post_id = #post.id
if #ratings1.save
redirect_to post_path(#post)
else
render 'new'
end
end
end
It appears that at no point in time are you every defining #ratings1 object, then you call the content method on it while the value of #ratings1 is nil and thats what cause the error. Maybe something like this should help:
class FpricesController < ApplicationController
before_action :authenticate_user!
def create
#post = Post.find(params[:post_id])
#fprice = Fprice.create(params[:fprice].permit(:content3))
#ratings1 = #post.ratings1s.last
#fprice.content3 = #post.price - #ratings1.content
#fprice.user_id = current_user.id
#fprice.post_id = #post.id
if #fprice.save
redirect_to post_path(#post)
else
render 'new'
end
end
end
I think this line is also a the problem
#fprice.content3 === #post.price - #ratings1.content
=== is an equality operator so I don't know why you would have it there replace it with this
#fprice.content3 = #post.price - #ratings1.content
I'm using rails 4.0.8. I added a comment section to a model called 'Things', but I keep getting the same error "param is missing or the value is empty: thing" when I press the submit comment button. It says the error is in the Things#Controller. What am I doing wrong?
UPDATE: I removed the url path from the form, but a new error returns "Couldn't find Thing without an ID". The error is in Comments#Controller.
VIEW FOR THING/SHOW
<div id= "thing">
<h1>
<%= #thing.name %>
</h1>
<br>
<div id= "commentsection">
Comments
<div id= "comments">
<br>
<% #thing.comments.each do |c| %>
<%= c.username %>
<br>
<%= c.text %>
<% end %>
<%= form_for #comment, :url => thing_path do |f| %>
<%= f.label :username %>
<%= f.text_field :username %>
<%= f.label :comment %>
<%= f.text_field :text %>
<%= f.submit "Enter", class: "btn btn-small btn-primary" %>
<% end %>
</div>
</div>
</div>
THINGS CONTROLLER
class ThingsController < ApplicationController
def show
#thing = Thing.find(params[:id])
#thing.comments.build
#comment = Comment.new
end
def index
end
def new
#thing = Thing.new
#things = Thing.all
end
def create
#thing = Thing.new(thing_params)
if #thing.save
redirect_to #thing
else
render 'new'
end
end
private
def thing_params
params.require(:thing).permit(:name, :avatar)
end
end
COMMENTS CONTROLLER (I put asterisks around the line where the error is)
class CommentsController < ApplicationController
def show
#comment = Comment.find(params[:id])
end
def new
#comment = Comment.new
#comments = Comment.all
end
def create
****#thing = Thing.find(params[:thing_id])****
#comment = #thing.comments.create(comment_params)
redirect_to thing_path(#thing)
end
end
private
def comment_params
params.require(:comment).permit(:user, :text, :upvotes, :downvotes, :thing_id)
end
end
ROUTES
Website::Application.routes.draw do
get "comments/new"
get "comments/show"
get "things/new"
root 'home_page#home'
get "all/things/new" => 'things#new'
get "all/allthings"
resources :things
resources :good_comments
get "things/show"
get "things/results"
end
You are posting the #comment form to post '/things' path.
<%= form_for #comment, :url => thing_path do |f| %>
It should just be <%= form_for #comment do %> (Rails is smart enough to plug in the comments_path) or if you feel like being more explicit (even though it's not necessary)
<%= form_for #comment, url: :comments_path do %>
Another note though, if you want that Comment to be tied to that specific Thing then in your models it should be
Class Thing
has_many :comments
end
Class Comment
belongs_to :thing
end
Then make sure in your database comment has a thing_id foreign_key field and then your form for comment should actually look like
<%= form_for #thing, #comment do %>
<% end %>
I have an html file as follows, located under views/admin/ve_files/new.html.erb
<div class="page-header">
<h3>Hi</h3>
</div>
<%= simple_form_for #ve_file do |f| %>
<%= f.file_field :file %>
<br><br>
<%= f.submit "Upload" %>
<% end %>
<br>
And then I have a controller located under controllers/admin/ve_files_controller.rb which looks like so
require 'CSV'
class Admin::VeFilesController < ApplicationController
layout 'admin'
def new
authorize! :create, :ve_file
#ve_file = VeFile.new
end
def create
puts "hello"
authorize! :create, :ve_file
#puts params
#ve_file = VeFile.new(params[:ve_file])
puts "okay"
if #ve_file.save
CSV.foreach(#ve_file.file.path) do |row|
puts row[0]
end
redirect_to admin_ve_path, :notice => 'Hi'
else
render :new
end
end
end
So when I click the Upload button in the html file, where does the program try to route me to? Where in the code is that specified? I get the following error and there is no output to the terminal:
Routing Error
uninitialized constant VeFilesController
because it should be Admin::VeFilesController
You are using a namespace called :admin, so that needs to be specified in your call to simple_form_for.
You can do so like this:
<%= simple_form_for [:admin, #ve_file] do |f| %>
My app has a user model and a post model, where user has_many posts and posts belong_to users. Posts are displayed on a user's profile page. I'd like for any user to be able to post on his own, or any other user's profile page. However, the problem I'm having is that while I know who is posting (current_user), I don't know whose profile current_user is on. I need to know this in order to assign the new post to that user's posts. How do I extract user id information from the profile currently being viewed, so I know where to assign the new post?
My micropost controller looks like:
class MicropostsController < ApplicationController
before_filter :authenticate_user!
def create
#user_of_page = User.find_by_name(params[:id])
#micropost = #user_of_page.microposts.build(params[:micropost])
if #micropost.save
flash[:success] = "Micropost created!"
redirect_to :back
else
redirect_to about_path
end
end
def destroy
end
end
But I'm getting a NoMethodError: undefined method `microposts' for nil:NilClass. I assume this is because I'm making some mistake with the creation of the user_of_page variable, but I don't know what that is!
SOLUTION
Thanks Sam. I took your advice and ended up doing it like this:
I added a column to my Micropost table called belongs_to_id.
I then passed the id of the user whose profile is being shown from the user show view to the micropost controller using a hidden field in the micropost form, like so:
<%= form_for #micropost do |f| %>
<%= render 'shared/error_messages', :object => f.object %>
<div class="field">
<%= f.label :content, "Why that mood?" %>
<%= f.text_area :content %>
</div>
<div class="field">
<%= f.hidden_field :author, :value => current_user.name %>
<%= f.hidden_field :belongs_to_id, :value => #user.id %>
<%= f.hidden_field :agree, :value => "0" %>
<%= f.hidden_field :disagree, :value => "0" %>
<%= f.hidden_field :amused, :value => "0" %>
</div>
<div class="actions">
<%= f.submit "Submit" %>
</div>
<% end %>
I then used this id value to search for the user to assign the post to, in the micropost controller, like so:
class MicropostsController < ApplicationController
before_filter :authenticate_user!
def create
#user_of_page = User.find(params[:micropost][:belongs_to_id])
#micropost = #user_of_page.microposts.build(params[:micropost])
if #micropost.save
flash[:success] = "Micropost created!"
redirect_to :back
else
redirect_to about_path
end
end
def destroy
end
end
Magic! Thanks again, you helped me to see it in the right way.
I would do it like this:
class profiles_controller < AC
...
def show
#profile = User.find(params[:id]).profile || current_user.profile
#post = Post.new
end
..
end
/profiles/show.html.erb
...
Name: <%= #profile.full_name %>
...
<%= form_for #post do |f| %>
<%= hidden_field_tag #profile.user %>
...
<% end %>
class microposts_controller < AC
def create
profile_user = User.find(params[:user_id]) # Owner of the profile current_user is on
..
end
end
Not tested. Hope this helps.