Couldn't find controller without an ID - ruby-on-rails

I'm trying to build Reddit on Rails by Schneems. And I keep getting this error at the point of submitting a new link.
ruby 1.9.3
Rails 4.2.0
What's wrong with my Links#Controller ?
class LinksController < ApplicationController
def show
#link = Link.find(params[:id])
end
def new
#link = Link.new
end
def create
#link = Link.new(links_params)
if #link.save
redirect_to(:action => 'show')
else
render('new')
end
end
private
def links_params
params.require(:link).permit(:title, :url)
end
end
The code should take me to a page showing submitted title and url. But it gives me :
ActiveRecord::RecordNotFound in LinksController#show
Couldn't find Link without an ID
Rails.root: C:/Users/Andrew/Documents/reddit_on_rails
Application Trace | Framework Trace | Full Trace
app/controllers/links_controller.rb:4:in `show'
New view is:
<h1>New link</h1>
<%= form_for #link do |f| %>
<% if #link.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#link.errors.count, "error") %> prohibited this link from being saved:</h2>
<ul>
<% #link.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %><br />
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :url %><br />
<%= f.text_field :url %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I've already added strong params to bundler but that did nothing.

I fixed it after four days(finally!).
So links controller should look like this:
def create
#link = Link.new(links_params)
if #link.save
render('show')
else
render('new')
end
Because before it was taking me to page localhost:3000/links/show and I needed localhost:3000/links/id

Related

Rails: How to pass instance variables from a controller to render partial

I am having trouble passing an instance variable (#article) from a controller (articles_controller.rb) to a partial render (_form.html.erb) in Ruby.
Here is the error from being sent back:
`undefined method `errors' for nil:NilClass`
articles_controller.rb:
class ArticlesController < ApplicationController
def new
end
def create
#article = Article.new(article_params)
if #article.save
redirect_to #article
else
render 'new'
end
end
def update
#article = Article.find(params[:id])
if #article.update(article_params)
redirect_to #article
else
render 'edit', :article => #article
end
end
def show
#article = Article.find(params[:id])
end
def index
#articles = Article.all
end
private
def article_params
params.require(:article).permit(:title, :text)
end
end
new.html.erb
<h1>New Article</h1>
<%= form_for :article, url: articles_path do |f|%>
<%= render partial: "form", :locals => {:article => #article} %>
<% end %>
<% link_to 'Back', articles_path %>
_form.html.erb
<% if #article.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#article.errors.count, "error") %> prohibited this
article from being saved:
</h2>
<ul>
<% #article.errors.full_messeages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :title %><br />
<%= f.text_field :title %>
</p>
<p>
<%= f.label :text %><br />
<%= f.text_area :text %>
</p>
<p>
<%= f.submit %>
</p>
Any help would be appreciated
def new
#article = Article.new
end
<%= render partial: "form", collection: #article %>
or even
<%= form_for #article do |f|%>
<%= render 'form' %>
<% end %>
depends on your needs
I had this challenge when working on a Rails 6 application.
I wanted to use an instance variable in a partial (app/views/shared/_header.html.erb) that was defined in a different controller (app/controllers/categories_controller.rb).
Here's how I did it:
The instance variable that I wanted to use is #categories which is defined as:
# app/controllers/categories_controller.rb
class CategoriesController < ApplicationController
def index
#categories = Category.all
end
.
.
.
end
Firstly, I rendered the app/views/shared/_header.html.erb partial in the app/views/layouts/application.html.erb and passed the #categories instance variable into it this way:
<%= render partial: '/shared/header', locals: { categories: #categories } %>
And then I used the instance variable in the partial this way:
# app/views/shared/_header.html.erb
<% #categories.each do |category| %>
<%= link_to category do %>
<%= category.name %>
<% end %>
<% end %>
However, this will require a controller action that sets a #categories instance variable for every controller views that will use the partial.
If you want to make variables globally available in your controllers and views, this could help: Rails: Set a common or global instance variable across several controller actions
That's all.
I hope this helps
You should do like this, removing #. You are passing it to local variable article so you could access it with article not #article:
<% if article.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(article.errors.count, "error") %> prohibited this
article from being saved:
</h2>
<ul>
<% article.errors.full_messeages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :title %><br />
<%= f.text_field :title %>
</p>
<p>
<%= f.label :text %><br />
<%= f.text_area :text %>
</p>
<p>
<%= f.submit %>
</p>
For more info, please take a look at passing-local-variables

Getting "param is missing or the value is empty: post" explained below

when i click new post and try to save a new post it gives me that error, then i go to the controller :
private
def posts_params
params.require(:post).permit(:title, :description)
end
and change 'require(:post)' to 'require(:posts' then i works
but then i try to edit the new post i just created and when i click to save it it gives me the same error, then i just change it back to 'required(:post)' and it works, why this is happening ? it's like a loop, if one works the other doesn't and to work i have to change that one thing
Controller:
class PostsController < ApplicationController
def index
#posts = Post.all
end
def edit
#posts = Post.find(params[:id])
end
def update
#posts = Post.find(params[:id])
if #posts.update(posts_params)
redirect_to #posts
else
render 'edit'
end
end
def new
#posts = Post.new
end
def create
#posts = Post.new(posts_params)
if #posts.save
redirect_to #posts
else
render 'new'
end
end
def show
#posts = Post.find(params[:id])
end
private
def posts_params
params.require(:post).permit(:title, :description)
end
end
view edit:
<h1>Editing post</h1>
<%= form_for(#posts) do |f| %>
<% if #posts.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#posts.errors.count, "error") %> prohibited
this post from being saved:
</h2>
<ul>
<% #posts.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :description %><br>
<%= f.text_area :description %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
<%= link_to 'Back', posts_path %>
view new:
<h1>New Article</h1>
<%= form_for :posts, url: posts_path do |f| %>
<% if #posts.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#posts.errors.count, "error") %> prohibited
this post from being saved:
</h2>
<ul>
<% #posts.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :description %><br>
<%= f.text_area :description %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
<%= link_to 'Back', posts_path %>
can someone point the problem out ?
You are mixing
form_for(#posts) do |f|
and
form_for :posts, url: posts_path
In your forms.
the :posts version will generate params[:posts] and the #posts version will generate params[:post]. Hence the issue you are seeing. Make sure you posts_params is as follows.
def posts_params
params.require(:post).permit(:title, :description)
end
then just change both of your forms to be
<%= form_for(#posts) do |f| %>
rails will figure out which to call automatically for you, so you will not have to specify the paths..
On a side note, I would probably change #posts to be #post everywhere but the index action, just so that it makes more sense, Since in new,edit,etc.. you are dealing with a singular post.
Since rails is looking at the Model/class of the variable when generating the routes (When given an instance variable) the name of the variable doesn't matter to the framework, but makes it easier (in my opinion) for the programmer to understand

Using a form to populate a database and land on a page with the information submitted

I have a form on my new view that takes in "url" and "title". When I submit my "url" & "title" I am taken to a blank create view. Ideally I would like to populate my database and land on a page that shows the title and link for that project.
This is my controller as it stands:
class LinksController < ApplicationController
def index
end
def new
#link = Link.new
end
def create
end
end
And this is the form:
<h1> This is New page for links </h1>
<%= form_for(#link) do |f| %>
<% if #link.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#link.errors.count, "error") %> prohibited this link from being saved:</h2>
<ul>
<% #link.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :url %><br />
<%= f.text_field :url %>
</div>
<div class="field">
<%= f.label :title %><br />
<%= f.text_field :title %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
How would I go about creating my methods(actions) to populate the database and then render what I am seeking? Ideally I'd like to see the flow behind how to think about the problem and the final code so that I can reverse engineer it.As long as I see it once I should be able to do it on my own next time.
You just have to do this
def create
#link = Link.new(params[:link])
if #link.save
redirect_to #link
else
render :new
end
end
def show
#link = Link.find(param[:id])
end
In routes.rb you will want to make sure you have the routes for this controller and its actions.
resources :links
That will provide you the standard CRUD HTTP methods with matching routes.

RAILS HABTM checkboxes don't update

I am trying to realize HABTM checkboxes following this tutorial:
http://www.justinball.com/2008/07/03/checkbox-list-in-ruby-on-rails-using-habtm/
While everything seems to work nicely the updates are not saved to my database.
My controller looks like the following:
class UserrolesController < ApplicationController
before_action :set_userrole
def edit
#projects=Project.all
end
def update
params[:userrole][:project_ids] ||= []
#userrole = Userrole.find(params[:id])
if #userrole.update_attributes(userrole_params)
flash[:notice] = "Settings have been saved."
redirect_to edit_userrole_url(#userrole)
else
flash.now[:error] = #userrole.errors
setup_form_values
respond_to do |format|
format.html { render :action => :edit}
end
end
end
private
def set_userrole
#userrole = Userrole.find(params[:id])
end
def userrole_params
params.require(:userrole).permit(:name, :project_ids)
end
end
My _form.html.erb like this:
<%= form_for(#userrole) do |f| %>
<% if #userrole.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#userrole.errors.count, "error") %> prohibited this person from being saved:</h2>
<ul>
<% #userrole.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="center">
<div class="field">
<%= f.label :Name %>
<%= f.text_field :name %>
</div>
<ul class="checkbox-list">
<% #projects.each do |project| -%>
<li><%= check_box_tag "userrole[project_ids][]", project.id, userrole_edits_project?(project) -%> <%= project.name -%></li>
<% end -%>
</ul>
<div class="actions">
<%= f.submit "Speichern", class: "btn btn-primary" %>
</div>
</div>
<% end %>
So I did everything like in the tutorial, the :name is saved without any problems, but the ids are not saved to the database. There is no error message. Does anybody has an idea what might go wrong? Maybe some missing permission somewhere?
So finally I found a work around for this problem.
I forced the update of project_ids by adding the following line in def update:
#userrole.project_ids=params[:userrole][:project_ids]

rails 3 associations error

I have a table pages and a table author. Each page belongs to one author. Created migrations for the tables and models as well. But getting this error while using it in form:
NoMethodError in Pages#new
Showing C:/rorapp/app/views/pages/_form.html.erb where line #1 raised:
undefined method `build' for nil:NilClass
Extracted source (around line #1):
1: <%= form_for(#page, #page.author.build) do |f| %>
2: <% if #page.errors.any? %>
3: <div id="error_explanation">
4: <h2><%= pluralize(#page.errors.count, "error") %> prohibited this post from being saved:</h2>
Trace of template inclusion: app/views/pages/new.html.erb
Rails.root: C:/rorapp
Application Trace | Framework Trace | Full Trace
app/views/pages/_form.html.erb:1:in `_app_views_pages__form_html_erb___998576952_54480300'
app/views/pages/new.html.erb:2:in `_app_views_pages_new_html_erb__638997451_40207104'
Request
Parameters:
None
Show session dump
Show env dump
Response
Headers:
None
Here is my model file for author:
class Author < ActiveRecord::Base
has_one :page
end
And page model:
class Page < ActiveRecord::Base
validates :title, :presence => true
belongs_to :author
end
And here is the snippet of model form :
<%= form_for(#page, #page.author.build) do |f| %>
<% if #page.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#page.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #page.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :title %><br />
<%= f.text_field :title %>
</p>
Any ideas how to go ahead with it?
thanks
EDIT - 1
Here is my action method called new :
def new
#page = Page.new
#page.build_author
end
And here is the form it is rendering:
<%= form_for(#page) do |f| %>
<% if #page.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#page.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #page.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :title %><br />
<%= f.text_field :title %>
</p>
<p>
<%= f.label :body %><br />
<%= f.text_area :body %>
</p>
<p>
<%= f.label :author %><br />
<%= f.text_field :author %>
</p>
<p>
<%= f.label :email %><br />
<%= f.text_field :email %>
</p>
<p>
<%= f.label :reference %><br />
<%= f.select(:reference,[['google',1],['yahoo',2],['MSN',3],['Ask',4]]) %>
</p>
<%= f.submit "Submit" %>
<% end %>
EDIT - 2
Here is my controller code:
class PagesController < ApplicationController
def index
#total = Page.count
#pages = Page.find(:all)
end
def show
#page = Page.find(params[:id])
end
def new
#page = Page.new
#page.build_author
end
def create
#page = Page.new(params[:page])
if #page.save
redirect_to pages_path, :notice => "The data has been saved!"
else
render "new"
end
end
def edit
#page = Page.find(params[:id])
end
def update
#page = Page.find(params[:id])
if #page.update_attributes(params[:page])
redirect_to pages_path, :notice => "Your post has been updated!"
else
render "edit"
end
end
def destroy
#page = Page.find(params[:id])
#page.destroy
redirect_to pages_path, :notice => "Your page has been deleted!"
end
end
you need to add *#page.build_author* in the new action of pages controller.
def new
#page = Page.new
#page.build_author
respond_to do |format|
format.html # new.html.erb
format.json { render json: #page }
end
end
It should be #page.build_author instead of #page.author.build. But the logic of this still doesn't look right to me.

Resources