I am using rails 4.1.6 I looked at the active record validations site and follow their direction, but nothing is displayed in the HTML even if there is an error.
However, when I do it in rails console it works.
post = Post.new #create an empty post to test
post.valid? #false
post.errors.messages #this is successfully generate the error message array
However, it doesn't display any error messages in HTML. In fact "#post.errors" doesn't even run
-Ruby code in html
<%= form_for #post, :method => :post do |f| %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.label :url %>
<%= f.text_field :url %>
<%= f.submit "Submit" %>
<% if #errors.any? %>
<ul>
<% #errors.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
<% end %>
<% end %>
-My PostsController
def create
# post = Post.new(title: params[:post][:title], url: params[:post][:url])
post = Post.new(post_params)
if post.save
redirect_to posts_path
else
#errors = post.errors.messages
redirect_to paths_path
end
end
private
def post_params
params.require(:post).permit(:title, :url)
end
-My post model
class Post < ActiveRecord::Base
validates :title, :length => {maximum: 140, minimum:1}, :presence => true
validates :title, :length => {maximum: 2083, minimum:1}, :allow_blank => true
end
When it comes to errors I do like to have a partial so I can keep my errors the same in the whole app like so:
app/views/shared/_errors.html.erb:
<% if object.errors.any? %>
<h5>The <%= t("activerecord.models.#{object.class.to_s.downcase}") %> could not be saved due to the following errors:</h5>
<ul>
<% object.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
<% end %>
And then for the views you want the errors to be displayed, just call:
<%= render 'shared/errors', object: #your_object %>
Hope this helps!
thanks for your help. Got some tip from my teacher it work. Simply use flash[:message] and it worked. Sorry for the trouble everyone
-My controller code
def create
post = Post.new(post_params)
if post.save
redirect_to :back
else
flash[:message] = post.errors.messages
redirect_to :back
end
end
-My HTML code
<%= simple_form_for #post, :method => :post do |f| %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.label :url %>
<%= f.text_field :url %>
<%= f.submit "Submit" %>
<%= flash[:message] %>
<% end %>
Related
I want to set up my models, such that my Posts has_many Comments and Comments has_many Replies. Comments are working fine. But my application starts breaking saying
undefined method `model_name' for "/posts/adas/comments/11/replies":String
when I try to setup the replies for comments. I cannot figure out what's triggering this error. I can add replies from my Rails console, and see them in the view, but adding the form_for tag breaks the code. Can anybody please point out what is the mistake and how I should be routing it?
Posts#show.html.erb
<h2>Comments</h2>
<% #post.comments.each do |comment| %>
<p>
<b><%= comment.username %></b>
<%= comment.name %>
<% if current_user.email == comment.username || current_user.admin? %>
<%= link_to 'Delete', [comment.post, comment],
:confirm => 'Are you sure?', :method => :delete %>
<% end %>
<p style = "text-indent: 3em">
<% comment.replies.each do |reply| %>
<i><%= reply.author %></i>
<%= reply.content %>
<% end %>
<%= form_for [#reply, post_comment_replies_path(#post, comment)] do |f| %>
<%= f.label :reply %>
<%= f.text_field :content %>
<%= f.submit("Reply") %>
<% end %>
<% end %>
</p>
</p>
<h3>Add a comment:</h3>
<%= form_for([#post, #post.comments.build]) do |f| %>
<%= f.label :comment %><br />
<%= f.text_area :name %>
<%= f.submit %>
<% end %>
replies_controller.rb
class RepliesController < ApplicationController
def create
#reply = #comment.replies.create(reply_params)
redirect_to post_path(#post)
end
private
def reply_params
params.require(:reply).permit(:content)
end
end
routes.rb
Rails.application.routes.draw do
devise_for :users, :controllers => { :omniauth_callbacks => "callbacks" }
root 'welcome#index'
resources :posts do
resources :comments do
resources :replies
end
member do
put "like", to: "posts#upvote"
end
end
end
You're almost there, but you're not passing the parameters in the proper way to get the result that you want. At the moment you're passing in a url string where rails is expecting a resource object, hence the undefined method exception.
form_for(record, options = {}, &block)
The method takes a record and a hash of options that are optional.
The suspect line is
<%= form_for [#reply, post_comment_replies_path(#post, comment)] do |f| %>
The square brackets should only be used to define a resource and its associated resources which are then used to generate a url path. You should also explicitly state your url in the options hash unless it can be inferred from the resources you pass into form_for.
So it should look something like this, keeping with the way you are doing things.
<%= form_for #reply, url: post_comment_replies_path(#post, comment) do |f| %>
That's the case if you want to specify a url in form_for. However, why don't you just allow rails to generate the url for you?
<%= form_for [#post, comment, #reply] do |f| %>
This way rails should handle the routes.
I've been trying to set up user authentication in my app using Authlogic, and I'm sure the problem is in my code but I can't seem to find it. When I hit the /login link, all works as expected, but my /logout wants to use GET instead of DELETE.
routing.db
Rails.application.routes.draw do
root 'comments#index'
resources :roles
resources :subjects
resources :comments
resources :topics
resources :users
resources :user_sessions, only: [:create, :destroy]
delete '/logout', to: 'user_sessions#destroy', as: :logout
get '/login', to: 'user_sessions#new', as: :login
end
user_sessions_controller
class UserSessionsController < ApplicationController
before_filter :require_no_user, :only => [:new, :create]
before_filter :require_user, :only => :destroy
def new
#user_session = UserSession.new
end
def create
#user_session = UserSession.new(user_session_params)
if #user_session.save
flash[:success] = "Welcome back!"
redirect_to root_path
else
render :action => :new
end
end
def destroy
current_user_session.destroy
flash[:success] = "Goodbye!"
redirect_to root_path
end
private
def user_session_params
params.require(:user_session).permit(:username, :password, :remember_me)
end
end
application.html.erb
<!DOCTYPE html>
<html>
<head>
<title><%= content_for?(:title) ? yield(:title) : "Untitled" %></title>
<%= stylesheet_link_tag "application" %>
<%= javascript_include_tag :defaults %>
<%= csrf_meta_tag %>
<%= yield(:head) %>
</head>
<body>
<div id="user_nav">
<% if current_user %>
<span><%= current_user.username %></span>
<%= link_to "Edit profile", edit_user_path(:current) %>
<%= link_to 'Sign Out', logout_path, :method => :delete %>
<% else %>
<%= link_to "Register", new_user_path %>
<%= link_to 'Sign In', login_path %>
<% end %>
</div>
<div id="container">
<% flash.each do |name, msg| %>
<%= content_tag :div, msg, :id => "flash_#{name}" %>
<% end %>
<%= content_tag :h1, yield(:title) if show_title? %>
<%= yield %>
</div>
</body>
</html>
Does anything here look wrong? Here's the error I'm getting:
In your application.html.erb file:
Change:
<%= javascript_include_tag :defaults %>
To:
<%= javascript_include_tag "application" %>
It should work after that!
Here is booking controller:
class BookingsController < ApplicationController
before_action :logged_in_user, only: [:create]
def new
#booking = Booking.new
end
def index
#bookings = Booking.all
end
def create
#booking = current_user.bookings.build(booking_params)
if #booking.save
flash[:success] = "Booking created!"
redirect_to root_url
else
render 'static_pages/home'
end
end
def show
#booking = Booking.find(params[:id])
end
def destroy
#booking = Booking.find(params[:id])
#booking.destroy
redirect_to bookings_path
end
private
def booking_params
params.require(:booking).permit(:date, :hour, :game)
end
end
When I post after the utf8 and authenticity token I don't understand why "#<\Booking:0x000001061928a8>\" instead of simply "booking" then the nested hash contains date, hour and game which I permit in the controller.
Here is the view:
<%= form_for(#booking) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :day %>
<%= date_field(#booking, :date) %>
<%= f.label :hour %>
<%= number_field(#booking, :hour, in: 8..19) %>
<%= f.label :game %>
<%= select(#booking, :game, [['Singles', 1], ['Doubles', 2]]) %>
<%= f.submit "Book", class: "btn btn-primary" %>
<% end %>
Any help much appreciated.
Ok it was simply that I wasn't using the the f variable of the form builder for the select boxes, originally I was but I'd had problems rendering the select boxes so I'd taken it out. Must have been due to a syntax error.
Here's the working form_for with a date picker and other select boxes:
<div class="field">
<%= form_for(#booking) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :day %>
<%= f.date_field :day %>
<%= f.label :hour %>
<%= f.number_field :hour, in: 8..19 %>
<%= f.label :game %>
<%= f.select :game, [['Singles', 1], ['Doubles', 2]] %>
<%= f.submit "Book", class: "btn btn-primary" %>
<% end %>
</div>
I'm having an unbelievable amount of trouble getting the Carrierwave :remove_avatar checkbox to work in my Devise profile edit form. I've been following the carrierwave documentation and wiki.
I've mounted the uploader to the User model. I've added :avatar and :remove_avatar to in the ApplicationController sanitizer
application_controller.rb
def configure_permitted_parameters
devise_parameter_sanitizer.for(:account_update) do |u|
u.permit(:first_name, :last_name, :email,
:password, :password_confirmation, :avatar, :remove_avatar)
end
devise_parameter_sanitizer.for(:sign_up) do |u|
u.permit(:first_name, :last_name, :email,
:password, :password_confirmation)
end
end
I've added the :remove_avatar to the edit form
/devise/registrations/edit.html.erb
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put, multipart: true }) do |f| %>
<%= f.label :avatar %><br />
<%= image_tag(resource.avatar_url(:thumb)) %>
<%= f.file_field :avatar, accept: 'image/jpeg,image/png' %>
<label>
<%= f.check_box :remove_avatar %>
Remove avatar
</label>
<%= f.label :first_name %><br />
<%= f.text_field :first_name, autofocus: true %>
<%= f.label :last_name %><br />
<%= f.text_field :last_name %>
<%= f.label :email %><br />
<%= f.email_field :email %>
<div><%= link_to 'Cancel', resource %> <%= f.submit "Update" %></div>
<% end %>
I'm not having any other problems with carrierwave except for removing the avatars. When I check the box and submit the form the picture is not removed.
I did a test where I used the users controller instead of devise's registrations controller and submitted the form to #user instead of resource and I was able to get it working. I'd rather stick to convention and use the registrations controller. What am I doing wrong or missing?
#user.remove_avatar!
#user.remove_avatar = true
#user.save
#user.reload
Try this, May help you.
Use this in your model:
after_commit :remove_avatar!, on: :destroy
I am following Ruby on Rails Guides and I have an error in rendering partial when I want to create a new article:
First argument in form cannot contain nil or be empty
Marked error is from partial _form.html.erb located in the same place as index:
<%= form_for #article do |f| %>
index.html.erb has link:
<%= link_to 'New article', new_article_path %>
controller:
def create
#article = Article.new(article_params)
#article.save
redirect_to #article
end
form partial:
<%= form_for #article do |f| %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :text %><br>
<%= f.text_area :text %>
</p>
<p>
<%= f.submit %><br>
</p>
<% end %>
new.html.erb which renders partial:
<h1>New article</h1>
<%= render 'form' %>
<%= link_to 'Back', articles_path %>
your controller needs a new method
def new
#article = Article.new
end
that way there's an #article object that the form_for can reference.
When you follow a new link, the new action is executed and the form is displayed. It's only when the form is submitted that the create action is executed.