Создание AJAX-формы для полиморфного объекта в Rails - PullRequest
2 голосов
/ 26 декабря 2010

Я пытаюсь создать форму AJAX для полиморфной ассоциированной модели.

Я создал «Комментарии», которые имеют полиморфную ассоциацию со всеми объектами, которые вы можете комментировать (например, профили пользователей, профили организации, события,и т.д.).

В настоящее время я могу добавлять комментарии к объектам, используя форму, созданную:

form_for [@commentable, @comment] do |f|

Я пытаюсь создать эту форму через Ajax, но продолжаю получать ошибки.

Я пробовал по крайней мере десять разных кусков кода, используя remote_form_tag, remote_form_for и т. Д. Со всеми различными опциями, и ничего не работает.Комментарий не вставляется в базу данных.

В частности, я пытался:

<% remote_form_for(:comment, :url => comments_path(@profile)) do |f| -%>

В моем маршруте route.rb много комментариев.И комментарии принадлежат профилю.Но когда я отправляю форму, ничего не происходит, и комментарий не публикуется в базе данных.

Может кто-нибудь сказать мне, что я делаю неправильно?

Для справки, вот моиконтроллеры.Комментарии контроллера:

class CommentsController < ApplicationController
  layout 'index'
  def index
    @commentable = find_commentable
    @comments = @commentable.comments
  end

  def show
    @comment = Comment.find(params[:id])
  end

  def new
    @comment = Comment.new
  end

  def create
    @commentable = find_commentable
    @comment = @commentable.comments.build(params[:comment])
    @comment.user_id = current_user.id
    if @comment.save
      responsetext = "<p><b>Comment: </b>" + @comment.content + "</p>"
      render :text => responsetext
    else
      responsetext = "error"
      render :text => responsetext
    end
  end

  def edit
    @comment = Comment.find(params[:id])
  end

  def update
    @comment = Comment.find(params[:id])
    if @comment.update_attributes(params[:comment])
      flash[:notice] = "Successfully updated comment."
      redirect_to @comment
    else
      render :action => 'edit'
    end
  end

  def destroy
    @comment = Comment.find(params[:id])
    @comment.destroy
    flash[:notice] = "Successfully destroyed comment."
    redirect_to comments_url
  end

  private

  def find_commentable
    params.each do |name, value|
      if name =~ /(.+)_id$/
        return $1.classify.constantize.find(value)
      end
    end
    nil
  end
end

Профиль контроллера:

class ProfilesController < ApplicationController
  # GET /profiles
  # GET /profiles.xml
  layout 'index'
  def index
    #@profile = Profile.find_by_user_id(current_user.id)

    @profile = current_user.profile
    @comment = Comment.new

    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @profile }
    end
  end

  # GET /profiles/1
  # GET /profiles/1.xml
  def show
    @profile = Profile.find(params[:id])
    @commentable = @profile
    @comment = Comment.new(:commentable => @profile)
    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @profile }
    end
  end

  # GET /profiles/new
  # GET /profiles/new.xml
  def new
    @profile = Profile.new

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @profile }
    end
  end

  # GET /profiles/1/edit
  def edit
    #@profile = Profile.find(params[:id])
    @profile = current_user.profile

  end

  # POST /profiles
  # POST /profiles.xml
  def create
    @profile = Profile.new(params[:profile])

    respond_to do |format|
      if @profile.save
        flash[:notice] = 'Profile was successfully created.'
        format.html { redirect_to(@profile) }
        format.xml  { render :xml => @profile, :status => :created, :location => @profile }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @profile.errors, :status => :unprocessable_entity }
      end
    end
  end

  # PUT /profiles/1
  # PUT /profiles/1.xml
  def update
    @profile = Profile.find(params[:id])

    respond_to do |format|
      if @profile.update_attributes(params[:profile])
        flash[:notice] = 'Profile was successfully updated.'
        format.html { redirect_to(@profile) }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @profile.errors, :status => :unprocessable_entity }
      end
    end
  end

  # DELETE /profiles/1
  # DELETE /profiles/1.xml
  def destroy
    @profile = Profile.find(params[:id])
    @profile.destroy

    respond_to do |format|
      format.html { redirect_to(profiles_url) }
      format.xml  { head :ok }
    end
  end
end

Вид:

<% remote_form_for([@commentable,@comment], :url => '/profiles/1/comments') do |f| -%>

<% #form_for [@commentable, @comment] do |f| %>



  <br /> 
<%= f.text_area :content %><br />

<%= submit_tag 'Post', :disable_with => 'Please wait...' %>

 <% end %>


    <h2>Comments</h2>
    <div id="comments">
    <% @profile.comments.each do |c| %>
      <div>
        <div style="float:left;width:50px">
        <%= image_tag c.user.profile.photo.url(:thumb) %>
        </div>
        <div style="float:left;padding:5px">
        <b><%= link_to c.user.name, profile_path(c.user.profile) %></b>
        <%=h c.content %><br />
        <font style="color:grey"><%=h distance_of_time_in_words(Time.at(c.created_at.to_i).to_i,Time.now.to_i, include_seconds = true)  %> ago</font>
        </div>
      </div>
    <div style="clear:both"></div>
    <% end %>
    </div>

1 Ответ

1 голос
/ 26 декабря 2010

Не могли бы вы вставить код контроллера?Вы должны иметь accepts_nested_attributes_for: комментарии в вашей модели профиля.В вашем контроллере вам нужно иметь

profile[:comments_attributes] = params[:comment]
profile.save
...