Polymorphic controller

Witajcie,

Pisze aplikacje, ktora ma dac mozliwosc komentowania roznych modeli,
postanowilem wiec zgodnie z metodyka DRY, pojsc w slady polymorphic controllers

Wszystko ladnie smiga do momentu, gdzie chce dodac funkcjonalnosc wystawiania komentarza jednemu uzytkownikowi przez drugiego

Na przyklad w momencie wyswietlania spotkania, w metodzie show, tworze nowa instancje potencjalnego komentarza, ktory byc moze jakis user chce wystawic na temat ogladanego spotkania:

def show @meeting = Meeting.find(params[:id]) @comment = Comment.new @comment.user = current_user @comment.meeting = @meeting render :layout => "meeting" end
Gdzie nastepnie w widoku mam

<% form_for ([@meeting, @comment]) do |f| %> <%= f.text_area :content, :cols => 55, :rows => 5 %> <%= f.submit 'Zapisz komentarz' %>t> <% end %>
Skoro wlascicielem komentarza jest model User, jak mam stworzyc formularz dajacy mozliwosc komentowania jednego Usera przez drugiego ?

<% form_for ([@user, @comment]) do |f| %> <%= f.text_area :content, :cols => 55, :rows => 5 %> <%= f.submit 'Zapisz komentarz' %>t> <% end %>
Po wyslaniu zwraca mi :

[quote]NoMethodError in CommentsController#create
undefined method `comments’ for nil:NilClass

/usr/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_support/whiny_nil.rb:52:in method_missing' /home/wojtek/git/ze/app/controllers/comments_controller.rb:26:increate’[/quote]
wklejka CommentsController@create na koniec:

[code] def create
@parent = parent_object
params[:comment][:user_id] = current_user.id
@comment = @parent.comments.build(params[:comment])

 if @comment.save
    redirect_to send("#{parent_type}_url", @parent)
  else
    render :action => "new"
  end

end[/code]
Dla niewtajemniczonych: kod ApplicationController (fragment)

[code] protected

class << self
  attr_reader :parents

  def parent_resources(*parents)
    @parents = parents
  end
end

def parent_id(parent)
request.path_parameters["#{parent}_id"]
end

def parent_type
self.class.parents.detect {|parent| parent_id(parent) }
end

def parent_class
parent_type && parent_type.to_s.classify.constantize
end

def parent_object
parent_class && parent_class.find_by_id(parent_id(parent_type))
end[/code]
Pozdrowienia

Powiem tak:

http://railscasts.com/episodes/154-polymorphic-association

[quote=gotar]Powiem tak:

http://railscasts.com/episodes/154-polymorphic-association[/quote]
Mozesz prosze jasniej ?

Obejrzyj, wklep do siebie, zastosuj. Tam masz własnie przykład komentowania, czyli cos co chcesz zrobic.

Spoko, z tym ze z polimorfizmem nie ma u mnie klopotu, dziala, problem jest zeby user mogl komentowac innego usera , w linku ktory podales taka opcja nie jest pokazana.

Ja zrobiłem coś takiego:
Stworzyłem model Użytkownika z imieniem
Meeting z titlem:
I Comment jako model polimorficzny :commentable,
Polimorfia wymaga dodatkowych pól w modelu: commentable_id:integer, commentable_type:string

schema.rb :

[code=ruby]create_table “comments”, :force => true do |t|
t.string “message”
t.integer “user_id”
t.datetime “created_at”
t.datetime “updated_at”
t.integer “commentable_id”
t.string “commentable_type”
end

create_table “meetings”, :force => true do |t|
t.string “title”
t.datetime “created_at”
t.datetime “updated_at”
end

create_table “users”, :force => true do |t|
t.string “name”
t.datetime “created_at”
t.datetime “updated_at”
end[/code]
Dodałem asocjacje do modeli:

[code=ruby]class User < ActiveRecord::Base
has_many :comments, :as => :commentable
has_many :comments_messages, :class_name => “Comment”
end

class Meeting < ActiveRecord::Base
has_many :comments, :as => :commentable
end

class Comment < ActiveRecord::Base
belongs_to :commentable, :polymorphic => true
belongs_to :author, :class_name => “User”, :foreign_key => “user_id”

end[/code]
Przy użytkowniku - relacja :comments to komentarze przypisane do użytkownika, :comments_messages, komentarze wydane (wiem że durna nazwa, ale to tak na prędce)
Komentarz ma relacje :author wskazującą autora komentarza

To wsio testujemy w rails console:

[code=ruby]u = User.create(:name => “Franek”)
u2 = User.create(:name => “Stefek”)

u.comments << Comment.create(:message => “Fajny kolo”, :author => u2)

puts u.comments.first.author.name
“Stefek”

puts u2.comments_messages.first.commentable.name
“Franek”

m = Meeting.create(:title => “Spotkanie przy piwku”)
m.comments << Comment.create(:message => “Fajnie było, trzeba powtórzyć”, :author => u)
puts m.comments.first.author.name
“Franek”[/code]
Jestem początkujący w ruby (i railsach, w javie dłubię ponad 10 lat) więc pewnie nie ustrzegłem się pewnych błędów, proszę o ocenę kogoś kto się zna.
wg mnie działa :wink:

Kolega pyta o kontrolery. Tak na szybko to masz niezdefiniowane @user w controlerze dlatego nie może zostać stworzony formularz