I have the following controller
class Dashboard::AvailabilitiesController < Dashboard::ApplicationController
def index
end
def new
end
def create
end
def destroy
end
end
with this model:
class Availability
include Mongoid::Document
include Mongoid::Timestamps
field :class_date, type: DateTime
belongs_to :kid
validates_uniqueness_of :class_date, :scope => [:class_date, :kid_id]
end
and this route:
namespace :dashboard do
resources :kids do
resources :availabilities
end
end
on my view, I have the following form:
= form_tag dashboard_kid_availabilities_url(current_kid), :method => 'post', :multipart => true do
.form-group
= datetime_select :class_date, {:start_year => Time.now.year, :order => [:day, :month, :year], :discard_minute => true}
.form-group
= submit_tag _('Save'), class: 'btn btn-blabloo btn-xs'
But I'm getting "uninitialized constant Dashboard::AvailabilitiesController" and I don't understand why. Also, I can remove the minutes selector of the forme using the discard_minute => true.
Any Idea please.
Thanks in advance
THe controller name should be within module Dashboard
module Dashboard
class AvailabilitiesController < ApplicationController
def index
end
def new
end
def create
end
def destroy
end
end
end
Another option is, probably, class Dashboard::AvailabilitiesController < ApplicationController.
Also make sure, that controller in under /controllers/dashboard/avaliabilities_controller.rb
Related
I have a Photo Share web app and I am trying to add comments in photos. I can't spot any mistakes. Maybe in the controller class in index function is the problem. There is an undefined method error when I try to show-post comments below the photo. Error in HAML code.
Error: - if #photo_comments.any?
Controller:
class CommentsController < ApplicationController
def index
#photo_comments = Comment.where(photo_id: => photo_id)
end
def create
#comment = Comment.create(user_id: params[:user_id], photo_id: params[:photo_id], text: params[:comment][:text])
flash[:notice] = "Successfully added a comment"
redirect_to :back
end
private
def comment_params
params.require(:comment).permit(:user_id, :photo_id, :text)
end
end
Model:
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :photo
end
Database:
class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.integer :user_id
t.integer :photo_id
t.string :text
t.timestamps
end
end
end
View:
%p Comments
- if #photo_comments.any?
- #photo_comments.each do |comment|
.bold-text= "#{comment.user.email}: "
.normal-text= comment.text
%br
- else
.text No comments for this photo yet!
%br
%br
%p
= form_for Comment.new(), :url => user_photo_comments_path do |form|
= form.label :text, 'Add a Comment'
%br
= form.text_area :text
%br
= form.submit 'Post'
Routes:
Rails.application.routes.draw do
get '/' => 'home#index'
resources :users do
resources :photos do
resources :comments
end
resources :follows
end
resources :tags, only: [:create, :destroy]
get '/log-in' => "sessions#new"
post '/log-in' => "sessions#create"
get '/log-out' => "sessions#destroy", as: :log_out
end
This line seems a bit problematic:
#photo_comments = Comment.where(photo_id: => photo_id)
I can spot a couple of potential errors here:
hash syntax: you are mixing both styles, you should use photo_id: photo_id or (Ruby pre 1.9) :photo_id => photo_id
the method or variable photo_id seems not defined in that controller, maybe you would mean params[:photo_id]?
There is definitely a syntax error on this line:
#photo_comments = Comment.where(photo_id: => photo_id)
also photo_id is not defined anywhere in the controller so maybe it should instead look like:
#photo_comments = Comment.where(photo_id: params[:photo_id])
?
The error undefined_method often comes when calling a method on a nil value. In your case instance variable #photo_comments is nil thus giving you undefined_method error in views.
These two line make no sense:
- if #photo_comments.nil?
- #photo_comments.each do |comment|
If the instance variable #photo_comments is nil then iterate of it? Of course, you will get an undefined method 'each' for nil:NilClass in that case.
I guess you mean something like this:
- unless #photo_comments.nil?
- #photo_comments.each do |comment|
I current have my project set up like this:
resources :boards, :path => '' do
resources :posts, :path => 'thread' do
resources :replies
On /board1/ only posts from board1 show, same for board2. In /board1/thread/1/ it shows post 1 and the replies to it.
However in /board2/thread/1/ the post that is showing is from board1/thread/1/, and in the reverse board1/thread/2/ shows the post from board2/thread/2/.
Each post has a related board_id in the db, and each reply has the related post_id in the db.
How can I keep these separate?
class Board < ActiveRecord::Base
has_many :posts
has_many :replies, through: :posts
include FriendlyId
friendly_id :name, use: :slugged
accepts_nested_attributes_for :posts, :replies
end
class Post < ActiveRecord::Base
belongs_to :board
has_many :replies, dependent: :destroy
accepts_nested_attributes_for :replies
include FriendlyId
friendly_id :pid, use: :slugged
after_create :set_pid
def set_pid
post_max = self.board.posts.maximum(:pid)
reply_max = self.board.replies.maximum(:pid)
if post_max.to_i < reply_max.to_i
self.update_attributes(:pid => reply_max.to_i + 1)
else
self.update_attributes(:pid => post_max.to_i + 1)
end
end
end
Code to display post in /:board_id/show:
<% #board.posts.find_each do |post| %>
<%= post.subject %>
<%= post.name %>
<%= post.email %>
<%= post.created_at %>
No.<%= post.pid %>
<%= link_to "[reply]", board_posts_path(#board, #post)%>
<br>
<%= post.comment %><br><br>
<%= render "replies/replies" %>
<% end %>
Code to display post in /:board_id/thread/:id:
<p>
<%= #post.subject %>
<%= #post.name %>
<%= #post.email %>
<%= #post.created_at %>
No.<%= #post.pid %>
<br>
<%= #post.comment %>
</p>
Edit:
class RepliesController < ApplicationController
def create
#board = Board.friendly.find(params[:board_id])
#post = Post.friendly.find(params[:post_id])
#reply = #post.replies.create(reply_params)
redirect_to #board
end
private
def reply_params
params.require(:reply).permit(:name, :email, :subject, :comment, :pid)
end
end
class PostsController < ApplicationController
def show
#boards = Board.all
#replies = Reply.all
#post = Post.friendly.find(params[:id])
end
def create
#board = Board.friendly.find(params[:board_id])
#post = #board.posts.create(post_params)
if #post.save
redirect_to #board
else render #board
end
end
private
def post_params
params.require(:post).permit(:name, :email, :subject, :comment, :pid)
end
end
The missing part here is the RepliesController which is the source of the problem if I got the question correctly.
Most probably you have there something like #replies = current_post.replies which fetch all replies of the given post regardless of the current board. Scoping post by board will solve the problem:
current_post = Post.find_by(board_id: params[:board_id], id: params[:post_id])
if current_post
#replies = current_post.replies
end
On your friendly_id declaration in the Post model, you don't have the pid as globally unique. Use this form of friendly_id, instead:
friendly_id :pid, use: :scoped, scope: :board
In this way, duplicate friendly_id values for pid are kept separate by the board that they belong to. This is necessary for slugging nested resources properly. The :scoped value says that it's for nested (scoped) models, and the scope: key indicates that posts is nested within boards. Note that you may have to do this with replies, as well.
You'll also want to make sure that your indexes for your :slug are correct. Typically when the :scope is incorrect, you'll find it when you try to save the record. In this case, it looks like the indexes might not be set correctly to ensure the uniqueness of the board name/post pid combination. Check out Friendly ID 4 Using scoped module for more information.
When you have the indexes sorted out, you'll find that inserting new records will require you to have the friendly_id (based on your pid) already assigned. You may also want to look into using slug candidates to dynamically generate the proper slug at creation time. Also check out slug candidates rails 4 for some usage information.
There is an association with course and course instance. When I visit the url /courses/1/course_instances/new, I get the error below.
This is the error I got:
No route matches {:controller=>"course_instances", :course_id=>nil}
Models
Course:
class Course < ActiveRecord::Base
attr_accessible :code, :credits, :description, :hours, :id, :name, :pass_mark
has_many :course_instances, :dependent => :destroy
accepts_nested_attributes_for :course_instances
end
Course Instance
class CourseInstance < ActiveRecord::Base
attr_accessible :end_date, :id, :start_date
belongs_to :course
end
Routes
Sis::Application.routes.draw do
resources :courses do
resources :course_instances
end
root :to => 'home#index'
end
Course Instance Controller
class CourseInstancesController < ApplicationController
before_filter :find_course
def new
#course_instance = #course.course_instances.build
respond_to do |format|
format.html
end
end
def find_course
#course = Course.find(params[:course_id])
end
end
new.html.erb
<%= form_for ([#course, #course_instance]) do |f| %>
---- excluded for brevity ----
Rake Routes
new_course_course_instance GET /courses/:course_id/course_instances/new(.:format) course_instances#new
Am not sure what I did but it started to work. I tried backtracking to recreate the error however I have been unsuccessful so far. Weird! Thanks for the help from everyone!
Hi i have this problem running the spec file.
this is the reparator model:
class Reparator < User
include Mongoid::Document
include Mongoid::Timestamps
field :private_reparator, :type => Boolean, :default => true
field :brand_name, :type => String
field :year_of_experience, :type => Integer, :default => 1
has_many :reparations
has_many :skills
validates_presence_of :skills, :year_of_experience
validates :year_of_experience, :numericality => {:greater_than_or_equal_to => 0}
end
This is the skill model:
class Skill
include Mongoid::Document
field :name, :type => String
belongs_to :reparator
validates_presence_of :name
validates_uniqueness_of :name
end
This is the controller:
class ReparatorsController < ApplicationController
respond_to :json
def index
#reparators = Reparator.all
respond_with #reparators
end
def show
#reparator = Reparator.find(params[:id])
respond_with #reparator
end
def create
#reparator = Reparator.new(params[:reparator])
#reparator.skills = params[:skills]
if #reparator.save
respond_with #reparator
else
respond_with #reparator.errors
end
end
def update
#reparator = Reparator.find(params[:id])
if #reparator.update_attributes(params[:reparator])
respond_with #reparator
else
respond_with #reparator.errors
end
end
def destroy
#reparator = Reparator.find(params[:id])
#reparator.destroy
respond_with "Correctly destroyed"
end
end
And this is the spec file for this controller (i'll just put the test that does't pass):
it "Should create an reparator" do
valid_skills = [FactoryGirl.create(:skill).id, FactoryGirl.create(:skill).id]
valid_attributes = {:name => "Vianello",
:email => "maremma#gmail.com",
:address => "viale ciccio",
:private_reparator => true
}
post :create, :reparator => valid_attributes, :skills => valid_skills
assigns(:reparator).should be_a Reparator
assigns(:reparator).should be_persisted
end
And this is the skill Factory girl:
FactoryGirl.define do
factory :skill do
sequence(:name) {|n| "skill#{n}"}
end
end
I think there is a typo in your spec. post :create, :reparator => valid_attributes, :skills => skills_ttributes should be post :create, :reparator => valid_attributes, :skills => skills_attributes instead.
The bad line is this one
#reparator.skills = params[:skills]
params[:skills] is an array of strings (the ids that have been passed) but the skills= method expects to be given actual instances of Skill and so blows up.
As well as skills=, mongoid also gives you a skill_ids= method which allows you to change which objects are associated by just assigning an array of ids. Alternatively, load the skills object your self and then to #reparator.skills = skills
I've used Virtual attributes in the past but I can't seem to get past this, and I know the answer is probably staring me in the face.
I have a model like so:
model Confirmation.rb
class Confirmation < ActiveRecord::Base
#attr_accessible :confirmation, :confirmation_token
#attr_accessible :confirmation_token
def confirmation_token
confirmation.confirmation_token if confirmation
end
def confirmation_token=(token)
self.confirmation = Booking.find_by_confirmation_token(token)
end
end
Your average scaffold controller for
confirmations_controller.rb
def new
#confirmation = Confirmation.new(:confirmation_token => params[:confirmation_token])
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #confirmation }
end
end
new.html.erb
<h1>New confirmation</h1>
<% form_for(#confirmation) do |f| %>
<%= f.error_messages %>
<%= f.hidden_field :confirmation_token %>
...
routes.rb
map.confirmation "confirmation/:confirmation_token", :controller => "confirmations", :action => "new"
map.resources :confirmations
error
undefined method `confirmation=' for #
In the console Booking.find_by_confirmation_token(token) with a given token works perfectly fine.
Any ideas? suggestions?
What you really need is attr_accessor :confirmation. There's a difference between attr_accessible and attr_accessor.
attr_accessor :confirmation
is same as
def confirmation
#confirmation
end
def confirmation=(value)
#confirmation = value
end
Now since it's such a common pattern ruby introduced helper methods for that.
Attr_accesible on the other hand is rails method, which marks that certain fields can be mass updated.
I think it should be either:
def confirmation_token=(token)
#confirmation = Booking.find_by_confirmation_token(token)
end
Or you should uncomment attr_accessible :confirmation or define #confirmation and #confirmation=.
class Confirmation < ActiveRecord::Base
belongs_to :bookings
#attr_accessible :confirmation, :confirmation_token
#attr_accessible :confirmation
def confirmation_token
#confirmation.confirmation_token if #confirmation
end
def confirmation_token=(token)
#confirmation = Booking.find_by_confirmation_token(token)
end
end
this worked... however just uncovering the attr_accessible :confirmation, did not. self.confirmation still returned undefined method...