I am trying to follow Ryan Bates screencast but have an error message. I did the following:
1) Create table
class CreateComments < ActiveRecord::Migration
def self.up
create_table :comments do |t|
t.references :commentable, :polymorphic => true
2) Setup models
class Comment < ActiveRecord::Base
belongs_to :commentable, :polymorphic => true
class Product < ActiveRecord::Base
has_and_belongs_to_many :categories
has_many :comments, :as => :commentable
class Category < ActiveRecord::Base
has_and_belongs_to_many :products
has_many :comments, :as => :commentable
3) Change controller show action
class CategoriesController < ApplicationController
def show
#category = Category.find_by_permalink(params[:id])
#commentable = #category
#comment = Comment.new(:commentable => #category)
end
4) Add a form to template views/categories/show.html.erb
<% form_for [#commentable, Comment.new] do |f| %>
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>
</p>
<p>
<%= f.label :content %><br />
<%= f.text_area :content %>
</p>
<p>
<%= f.submit 'Submit' %>
</p>
<% end %>
5) After that I get error message by accessing /categories/my-category-permalink
NoMethodError in Categories#show
undefined method `category_comments_path' for #<ActionView::Base:0x69a9254>
Could you help me to understand what I did wrong?
In the original screencast Ryan accesses comments by /categories/permalink/comments using nested associations, but I don't need that. I want to write comments directly from my polymorphic objects.
Thanks
The problem was in routes settings. I thought that since I don't use nested resources, I can keep routes unchanged. Well, now I know that I was wrong... :) Add this to fix the problem:
map.resources :categories :has_many => :comments
map.resources :products, :has_many => :comments
Related
I am getting following error :
undefined method `recommendations_path' for #<#<Class:0x0078>>
I have Recommendation model
class Recommendation < ActiveRecord::Base
belongs_to :user
belongs_to :recommended_user, class_name: "User", foreign_key: :recommended_user_id
end
I have user model
class User < ActiveRecord::Base
has_many :recommendations
................
end
In recommendation controller
def new
#recommendation = current_user.recommendations.new
end
In new.html.erb
<%= form_for #recommendation do |f| %>
<%= f.text_field :relationship %>
<%= f.text_field :comment %>
<%= f.submit %>
<% end %>
My routes, where I think problem is:
devise_for :users
resources :users, only: [:show] do
collection do
get :customer_signup
get :employee_signup
end
member do
get :choose_role
get :become_a_customer
get :become_a_employee
end
end
resources :users do
resources :recommendations
end
Thats actually when the form is trying to identify the path for your #recommendation.
According to your routes.rb your form must be:
<%= form_for [:user, #recommendation] do |f| %>
Ruby on rails newbie here, I have previously been using CakePHP and wanted to allow my create comments controller to create events for two models, any help please?
My comments controller:
def create
#event = Event.find(params[:event_id])
#comment = #event.comments.create(params[:comment].permit(:commenter, :body))
redirect_to event_path(#event)
end
def create
#venue = Venue.find(params[:venue_id])
#comment = #venue.comments.create(params[:comment].permit(:commenter, :body))
redirect_to venue_path(#venue)
end
My create comments view:
<h2>Add a comment:</h2>
<%= form_for([#event, #event.comments.build]) do |f| %>
<p>
<%= f.label :commenter %><br />
<%= f.text_field :commenter %>
</p>
<p>
<%= f.label :body %><br />
<%= f.text_area :body %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
This is a classic example for polymorphic association.
There would be a bit of tweaking to get it to work right.
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
...
end
class Venue < ActiveRecord::Base
has_many :comments, as: :commentable
...
end
class Event < ActiveRecord::Base
has_many :comments, as: :commentable
...
end
This will add to your comments Model another attribute called commentable_type so you could differ the types of comments for each Model (Venue, Event)
You would have to run a migration that looks mostly like this
def change
create_table :comments do |t|
t.integer :commenter
t.text :body
t.integer :commentable_id
t.string :commentable_type
t.timestamps
end
end
Now when you migrate you can go to your rails console and see that if you try
Venue.first.comments << Comment.create!(:body => "Body", :commenter => "Guy") # or commenter => 1 depending on your schema
It will be saved to the database as a comment and you can also do the same thing for Event
Now as for your comments controller, I would advise against creating a global comments controller and rather have follow the RESTful approach and have each controller handle his comments.
I.E
# routes.rb
resources :venues
resources :comments
end
resources :events do
resources :comments
end
This way you can both tweak your views according to each controller (venue / events), you follow the RESTful approach as you can use this with either HTML/JSON/XML, you get nicer routes
/events/1/comments # index for all the comments for event 1
/events/1/comments/new # your add a comment form
and same goes for venue.
You can find more info on associations in here http://guides.rubyonrails.org/association_basics.html#polymorphic-associations
Good luck!
I'd like to have a form where groups can add their interests and this form should help them with autocompletion.
As this is a many-to-many relation, I don't understand how to implement it
class Group < ActiveRecord::Base
attr_accessible :description, :name, :project_id, :interests
before_save :get_next_available_name
has_many :users
belongs_to :project
has_and_belongs_to_many :interests
end
class Interest < ActiveRecord::Base
attr_accessible :name
has_and_belongs_to_many :groups
end
In the view I have:
<%= simple_form_for #group do |f| %>
<%= f.autocomplete_field :interests, autocomplete_interest_name_groups_path %>
<%= f.submit "Interesse eintragen" %>
<% end %>
Of course I entered "rails g autocomplete:install"
I probably have to edit the routes and added this to the routes.rb:
resources :groups do
get :autocomplete_interest_name, :on => :collection
end
UPDATE:
As Saurabh suggested, I put he "autocomplete :interest, :name" in the controller, not in the model.
But I have two problems now:
First: There is no autocomplete coming up.
Second: After adding 'ruby' Interest and submitting the form: In the input field there is written this:
[#<Interest id: 38, name: "ruby", created_at: "2013-02-28 09:25:53", updated_at: "2013-02-28 09:25:53">]
But of course the field itself should be empty.
If this gem is not compatible with Rails 3.2, someone should tell me...
Define the autocomplete in your controller and remove it from model as:
class GroupsController < ApplicationController
autocomplete :interest, :name
# ...
# ...
end
UPDATE:
According to your question update, this is what you need to do now:
Your view:
<%= simple_form_for #group do |f| %>
<%= f.autocomplete_field :interests, autocomplete_interest_name_groups_path %>
<%= f.submit "Interesse eintragen" %>
<% end %>
More from the rails3 jquery autocomplete sources.
I am creating an app that allows users to create and apply for jobs.
The issue I am having is in getting the associations correct between my three models.
Currently I have the following:
class App < ActiveRecord::Base
belongs_to :job
belongs_to :user
end
class Job < ActiveRecord::Base
belongs_to :user, :dependent => :destroy
has_many :apps, :through => :users
end
class User < ActiveRecord::Base
has_many :jobs
has_many :apps, :through => :jobs
end
In my database table for Apps I have two additional columns for user_id and job_id so that the association can be made correctly there.
I am also unsure how I would create a form for say a new application. Currently I have used the following but because I don't have apps as a nested resource of users I am unsure if this is what's causing the issues:
class AppsController < ApplicationController
def new
#user = current_user
#app = #user.apps.build
end
def create
#user = current_user
#app = #user.apps.create(params[:app])
if #app.save
redirect_to user_path
else
render new_app_path
end
end
and
<%= form_for [#app] do |f| %>
<div class = "field">
<%= f.label :name %>
<%= f.text_field :name %>
</div>
<div class = "field">
<%= f.label :cover_letter %>
<%= f.text_field :cover_letter %>
</div>
<div class = "field">
<%= f.label :cv %>
<%= f.text_field :cv %>
</div>
<%= f.submit "Submit" %>
<% end %>
It would be great if someone could provide an example of how they would setup the associations for this app and how they would ensure that the related forms worked with this setup.
Thanks in advance for your help!
I have also pushed my app to Github in case that helps anyone: Github Link
I think there will be relationship many-to-many between users and jobs.And applications can act as join table (as jobs_users).
so models ...
class App < ActiveRecord::Base
belongs_to :job
belongs_to :user
end
class Job < ActiveRecord::Base
has_many :users
has_many :apps, :through => :apps
end
class User < ActiveRecord::Base
has_many :jobs,:dependent => :destroy
has_many :apps, :through => :apps
end
And for nested form go through this
http://railscasts.com/episodes/196-nested-model-form-part-1?view=asciicast
I have these models:
model 1:
module Ems
class Article < ActiveRecord::Base
has_many :images, :as => :imageable
accepts_nested_attributes_for :images
end
end
model 2:
module Ems
class Image < ActiveRecord::Base
belongs_to :imageable, :polymorphic => true
end
end
view:
= form_for #article do |f|
%div
= f.label :title
= f.text_field :title
%div
- f.fields_for :images do |builder|
= builder.label :title
= builder.text_field :title
I don't get any errors however I also dont get the form fields for the embedded image form. All I get is an empty DIV.
Can anyone point me in the right direction?
Thanks
try after replacing - with = at where you are calling fields_for
= f.fields_for :images do |builder|
The fields_for returns form HTML, so you need to render it on UI.