Problem z przekazaniem ID usera i jego include

Witam wszystkich,

Pisze sobie aplikację i doszedłem do momentu w którym muszę napisać Forum dyskusyjne.
Teraz sprawa wygląda tak, że mam 3 tabele:

[code] create_table “forum_categories”, :force => true do |t|
t.string “title”
t.text “text”
t.integer “position”
t.integer “mode_private”, :limit => 1, :default => 0
t.datetime “created_at”
t.datetime “updated_at”
end

create_table “forum_posts”, :force => true do |t|
t.text “text”
t.integer “user_id”
t.integer “thread”
t.datetime “created_at”
t.datetime “updated_at”
end

create_table “forum_threads”, :force => true do |t|
t.string “title”
t.integer “parent_id”
t.datetime “created_at”
t.datetime “updated_at”
end[/code]
Dokładnie jak to wygląda (relacje) przedstawiam Wam model:

[code]class ForumCategory < ActiveRecord::Base
has_many :forum_threads, :foreign_key => ‘parent_id’, :dependent => :destroy
validates_length_of :title, :within => 4…32, :message => ‘Długość kategorii musi mieć od 4 do 32 znaków’
acts_as_list

def to_param
“#{id},#{title.parameterize}”
end

end[/code]

class User < ActiveRecord::Base has_many :forum_posts ...

[code]class ForumThread < ActiveRecord::Base
belongs_to :forum_category
belongs_to :user, :foreign_key => ‘user_id’

has_many :forum_posts, :foreign_key => ‘thread’, :dependent => :destroy
validates_length_of :title, :within => 5…32, :message => ‘Temat musi mieć od 5 do 32 znaków’

def post=(post)
forum_posts.build(post)
end

def to_param
“#{id},#{title.parameterize}”
end

end[/code]

class ForumPost < ActiveRecord::Base belongs_to :forum_thread belongs_to :user validates_length_of :text, :within => 5..1024, :message => 'Treść musi mieć conajmniej 5 znaków' end
Teraz mam pytanie, mianowicie, dlaczego nie user_id nie zawiera joina do tabeli usera, tylko samo id? wpisując przykładowo <%= post.user_id.login %> otrzymuję komunikat, że nie login == nil.
Drugie pytanie to, w jaki sposób przekazać przez formularz, id usera przy tworzeniu topicu? Dodam, że temat tworzę w ten sposób:

[code]<% title ‘Dodaj nowy temat’ %>

<% form_for @topic, :url => topic_insert_forum_url do |form| %>

<% for thread in @topic.forum_posts %>
<% fields_for ‘forum_thread[post]’, thread do |form| %>

<% end %> <% end %>
<%= form.label :title, 'Tytuł' %>
<%= form.text_field :title %>
<%= error_message_on @topic, :title %>
<%= form.label :text, 'Treść wpisu' %>
<%= form.text_area :text %>
<%= error_message_on thread, :text %> <%= form.hidden_field :user_id, :value => current_user.id %> #-- nie chcę przekazywać tego z poziomu szablonu...
<%= form.submit 'Dalej' %>
<% end %>[/code] Pozdrawiam ;)
  1. post.user.login
  2. jak topic może tworzyć tylko zalogowany user, to brać to z sesji. Inaczej może dawać jako parametr lub w formularzu dac hidden_field

IMO powinno być post.user.login.

Masz, powiedzmy, taki kod w kontrolerze odpowiedzialnym za tworzenie postów:

def create @post = Post.new(params[:post]) if @post.save flash[:notice] = "Successfully created post." redirect_to root_url else render :action => 'new' end end
Wystarczy dodać jedną linijkę:

def create @post = Post.new(params[:post]) @post.user_id = current_user.id if @post.save flash[:notice] = "Successfully created post." redirect_to root_url else render :action => 'new' end end
Mam nadzieję, że pomogłem.

@rav:
masz rację, ale to by było za proste;)
Chodzi o to, że muszę odwołać się przez forum_thread do forum_post, aby stworzyć nowy temat wraz z postem.

def create @category = ForumCategory.find(params[:id]) @topic = @category.forum_threads.new @topic.forum_posts.build end

[code]<% title ‘Dodaj nowy temat’ %>

<% form_for @topic, :url => topic_insert_forum_url do |form| %>

<% for thread in @topic.forum_posts %>
<% fields_for ‘forum_thread[post]’, thread do |form| %>

<% end %> <% end %>
<%= form.label :title, 'Tytuł' %>
<%= form.text_field :title %>
<%= error_message_on @topic, :title %>
<%= form.label :text, 'Treść wpisu' %>
<%= form.text_area :text %>
<%= error_message_on thread, :text %>
<%= form.submit 'Dalej' %>
<% end %>[/code] [code]class ForumThread < ActiveRecord::Base belongs_to :forum_category belongs_to :user, :foreign_key => 'user_id'

has_many :forum_posts, :foreign_key => ‘thread’, :dependent => :destroy
validates_length_of :title, :within => 5…32, :message => ‘Temat musi mieć od 5 do 32 znaków’

def post=(post)
forum_posts.build(post)
end

def to_param
“#{id},#{title.parameterize}”
end

end[/code]
Chciałbym w ten sposób dodać post. Wszystko śmiga, bez najmniejszego problemu, jednak potrzebuję dodać jeszcze id usera do post.

Najprościej było by zrobić coś w stylu:

[code]class ForumThread < ActiveRecord::Base
belongs_to :forum_category
belongs_to :user, :foreign_key => ‘user_id’

has_many :forum_posts, :foreign_key => ‘thread’, :dependent => :destroy
validates_length_of :title, :within => 5…32, :message => ‘Temat musi mieć od 5 do 32 znaków’

def post=(post)
post[user_id] = current_user
forum_posts.build(post)
end

def to_param
“#{id},#{title.parameterize}”
end

end[/code]
Ale to nie jest zbyt zgodne z logiką MVC, takie rzeczy powinno się w kontrolerze robić. Ale to tylko moja opinia, i drugie pytanie - jak to zrobić?:slight_smile:

Albo nie do końca rozumiem, albo za dużo kombinujesz:

@post = @topic.forum_posts.build(params[:post].merge(:user => current_user))

@nairda, niby, tak, ale build jest tworzony w modelu, a nie w kontrolerze, a inicjacja bo w kontrolere nie wiele daje:

[code] def new_topic
@category = ForumCategory.find(params[:id])
@topic = @category.forum_threads.new
@topic.forum_posts.build
end

def topic_insert
@category = ForumCategory.find(params[:id])
@topic = @category.forum_threads.new(params[:forum_thread])

if @topic.save
  flash[:notice] = 'Poprawnie dodano nowy temat'
  redirect_to forum_path(@category)
else
  render :action => 'new_topic'
end

end[/code]
Jeszcze raz:
Tworzę nowy temat w którym w formularzu wykorzystuję 2 tabele, połączone ze sobą relacjami has_many, belongs_to. Są to forum_thread i forum_posts. W forum_thread zapisywany jest ID kategorii oraz tytuł wątku, natomiast w forum_posts jest zapisana treść posta wraz z datą publikacji (to robi rails:)) oraz userem, którego nie wiem jak dopisać.

Korzystam z form_for i chcę, aby tak zostało, jednak nie wiem jak w tym przypadku do forum_posts dopisać usera, skoro całośc generowana jest w modelu:

[code]class ForumThread < ActiveRecord::Base
belongs_to :forum_category
belongs_to :user, :foreign_key => ‘user_id’

has_many :forum_posts, :foreign_key => ‘thread’, :dependent => :destroy
validates_length_of :title, :within => 5…32, :message => ‘Temat musi mieć od 5 do 32 znaków’

def post=(post)
forum_posts.build(post)
end

def to_param
“#{id},#{title.parameterize}”
end

end[/code]
@nairda: twoje rozwiązanie jest idealne, jednak potrzebuję albo zrobić to w modelu, albo z poziomu kontrolera dopisać do tablicy post dodać w jakiś sposób id usera.

== edit ==
znalazłem rozwiązanie pisząc odpowiedź do tego tematu (“z poziomu kontrollera dopisać do tablicy post…” :)) jednak nie do końca wiem czy jest ono mądre:)

[code] def new_topic
@category = ForumCategory.find(params[:id])
@topic = @category.forum_threads.new
@topic.forum_posts.build
end

def new_post
@topic = ForumThread.find(params[:id])
@post = @topic.forum_posts.new
end

def insert_post
@topic = ForumThread.find(params[:id])
@post = @topic.forum_posts.new(params[:forum_post].merge(:user => current_user))

if @post.save
  flash[:notice] = 'Poprawnie dodano odpowiedź'
  redirect_to thread_forum_url(@topic)
else
  render :action => 'new_post'
end

end

def topic_insert
@category = ForumCategory.find(params[:id])
@topic = @category.forum_threads.new(params[:forum_thread])
@topic.forum_posts.build(params[:forum_thread][:post].merge(:user => current_user))

if @topic.save
  flash[:notice] = 'Poprawnie dodano nowy temat'
  redirect_to forum_path(@category)
else
  render :action => 'new_topic'
end

end[/code]
Natomiast w modelu dla post=(post) dałem zwykłe return.