Ruby on Rails,使用 link_to_remote 单击更新 div

发布于 2024-09-27 12:29:09 字数 3669 浏览 2 评论 0原文

我正在实施类似于 Netflix 的 5 星评论评级。目标是拥有一个“评级”div,既可以通过单击其中一颗星星来输入评级,也可以显示当前评级。我想在用户输入新评级后更新“评级”。

目前,我可以添加评级并创建与评级资产的关联,但在保存数据后无法刷新“评级”div...我缺少什么?

评级控制器:

  def create
    case params[:rating][:rateable_type]
    when "course"
      @course = Course.find(params[:rating][:rateable_id])
    end

    @rating = Rating.new(params[:rating])

    if @rating.save
      @course.ratings_sum += @rating.rating
      @course.save
      flash[:notice] = 'Rating was successfully created.'
      render :partial => "ratings/rating", :locals => { :asset => @course }
    end
  end

部分评级 ( ratings/_ating.html.erb):

<div id="rating">
<%= number_with_precision(asset.avg_rating, :precision => 1) %>/5 Stars<br>

<ul class='star-rating'>
    <li class='current-rating' style='width:<%= (asset.avg_rating * 17).to_s -%>px;'>
        Currently <%= number_with_precision(asset.avg_rating, :precision => 1) %>/5 Stars.
    </li>
    <li>
        <%= link_to_remote "1", :url => {:controller => "ratings", :action => :create},
            :update => 'rating', :partial => "ratings/rating",
            :rating => {:rateable_type => asset.class.to_s.downcase, :rateable_id => asset.id, :rating => 1},
            :method => :post, :class => 'one-star', :name => '1 star out of 5' %>
    </li>
    <li>
        <%= link_to_remote "2", ...
</ul>
</div>

Routes.rb:

map.resources : ratings

控制台输出:

Processing RatingsController#create (for 127.0.0.1 at 2010-10-13 15:09:14) [POST]
  Parameters: {"rating"=>{"rating"=>"1", "rateable_type"=>"course", "rateable_id"=>"42"}, "authenticity_token"=>"IodWLi9JO56tco6rgQH5vtdvKTNsE/Fih0k9jWptZmk=", "update"=>"rating"}
  Course Columns (1.8ms)   SHOW FIELDS FROM `courses`
  Course Load (0.1ms)   SELECT * FROM `courses` WHERE (`courses`.`id` = 42) 
  Rating Columns (0.9ms)   SHOW FIELDS FROM `ratings`
  SQL (0.1ms)   BEGIN
  Rating Create (0.2ms)   INSERT INTO `ratings` (`rating`, `rateable_type`, `created_at`, `rateable_id`, `updated_at`, `user_id`) VALUES(1, 'course', '2010-10-13 22:09:14', 42, '2010-10-13 22:09:14', 0)
  Course Load (0.3ms)   SELECT * FROM `courses` WHERE (`courses`.`id` = 42) 
  Course Update (0.3ms)   UPDATE `courses` SET `ratings_count` = COALESCE(`ratings_count`, 0) + 1 WHERE (`id` = 42) 
  SQL (0.4ms)   SHOW TABLES
  Course Update (0.3ms)   UPDATE `courses` SET `updated_at` = '2010-10-13 22:09:14', `ratings_sum` = 20 WHERE `id` = 42
  SQL (0.8ms)   COMMIT
  SQL (0.1ms)   BEGIN
  Course Update (0.2ms)   UPDATE `courses` SET `updated_at` = '2010-10-13 22:09:14', `ratings_sum` = 20 WHERE `id` = 42
  SQL (0.1ms)   COMMIT
Rendered ratings/_rating (9.7ms)
Completed in 43ms (View: 11, DB: 6) | 200 OK [http://localhost/ratings?rating%5Brateable_id%5D=42&rating%5Brateable_type%5D=course&rating%5Brating%5D=1&update=rating]

这是“link_to_remote”生成的代码

<a onclick="new Ajax.Request('/ratings?rating%5Brateable_id%5D=42&amp;rating%5Brateable_type%5D=course&amp;rating%5Brating%5D=1&amp;update=rating_bar', {asynchronous:true, evalScripts:true, parameters:'authenticity_token=' + encodeURIComponent('IodWLi9JO56tco6rgQH5vtdvKTNsE/Fih0k9jWptZmk=')}); return false;" name="1 star out of 5" method="post" href="#" class="one-star">1</a>

I'm implementing a netflix-like 5 star review ratings. The goal is to have a "rating" div that serves both to enter the rating by clicking on one of the stars, as well to display the current rating. I want to update the "rating" after a users enters a new rating.

For now, I can add a rating and create the association to the rated asset, but can't refresh the "rating" div after the data is saved... What am I missing?

Ratings Controller:

  def create
    case params[:rating][:rateable_type]
    when "course"
      @course = Course.find(params[:rating][:rateable_id])
    end

    @rating = Rating.new(params[:rating])

    if @rating.save
      @course.ratings_sum += @rating.rating
      @course.save
      flash[:notice] = 'Rating was successfully created.'
      render :partial => "ratings/rating", :locals => { :asset => @course }
    end
  end

Ratings partial (ratings/_rating.html.erb):

<div id="rating">
<%= number_with_precision(asset.avg_rating, :precision => 1) %>/5 Stars<br>

<ul class='star-rating'>
    <li class='current-rating' style='width:<%= (asset.avg_rating * 17).to_s -%>px;'>
        Currently <%= number_with_precision(asset.avg_rating, :precision => 1) %>/5 Stars.
    </li>
    <li>
        <%= link_to_remote "1", :url => {:controller => "ratings", :action => :create},
            :update => 'rating', :partial => "ratings/rating",
            :rating => {:rateable_type => asset.class.to_s.downcase, :rateable_id => asset.id, :rating => 1},
            :method => :post, :class => 'one-star', :name => '1 star out of 5' %>
    </li>
    <li>
        <%= link_to_remote "2", ...
</ul>
</div>

Routes.rb:


map.resources :ratings

Output from the console:

Processing RatingsController#create (for 127.0.0.1 at 2010-10-13 15:09:14) [POST]
  Parameters: {"rating"=>{"rating"=>"1", "rateable_type"=>"course", "rateable_id"=>"42"}, "authenticity_token"=>"IodWLi9JO56tco6rgQH5vtdvKTNsE/Fih0k9jWptZmk=", "update"=>"rating"}
  Course Columns (1.8ms)   SHOW FIELDS FROM `courses`
  Course Load (0.1ms)   SELECT * FROM `courses` WHERE (`courses`.`id` = 42) 
  Rating Columns (0.9ms)   SHOW FIELDS FROM `ratings`
  SQL (0.1ms)   BEGIN
  Rating Create (0.2ms)   INSERT INTO `ratings` (`rating`, `rateable_type`, `created_at`, `rateable_id`, `updated_at`, `user_id`) VALUES(1, 'course', '2010-10-13 22:09:14', 42, '2010-10-13 22:09:14', 0)
  Course Load (0.3ms)   SELECT * FROM `courses` WHERE (`courses`.`id` = 42) 
  Course Update (0.3ms)   UPDATE `courses` SET `ratings_count` = COALESCE(`ratings_count`, 0) + 1 WHERE (`id` = 42) 
  SQL (0.4ms)   SHOW TABLES
  Course Update (0.3ms)   UPDATE `courses` SET `updated_at` = '2010-10-13 22:09:14', `ratings_sum` = 20 WHERE `id` = 42
  SQL (0.8ms)   COMMIT
  SQL (0.1ms)   BEGIN
  Course Update (0.2ms)   UPDATE `courses` SET `updated_at` = '2010-10-13 22:09:14', `ratings_sum` = 20 WHERE `id` = 42
  SQL (0.1ms)   COMMIT
Rendered ratings/_rating (9.7ms)
Completed in 43ms (View: 11, DB: 6) | 200 OK [http://localhost/ratings?rating%5Brateable_id%5D=42&rating%5Brateable_type%5D=course&rating%5Brating%5D=1&update=rating]

And here is the code generated by "link_to_remote"

<a onclick="new Ajax.Request('/ratings?rating%5Brateable_id%5D=42&rating%5Brateable_type%5D=course&rating%5Brating%5D=1&update=rating_bar', {asynchronous:true, evalScripts:true, parameters:'authenticity_token=' + encodeURIComponent('IodWLi9JO56tco6rgQH5vtdvKTNsE/Fih0k9jWptZmk=')}); return false;" name="1 star out of 5" method="post" href="#" class="one-star">1</a>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

荒人说梦 2024-10-04 12:29:09

找到了解决方法:我将“更新”和“部分”参数从“评级部分”移至“评级>”创建控制器...这是现在的样子:

评级控制器:我更改了渲染选项

  render :update do |page|
    page.replace_html  'star-ratings-block', :partial => 'ratings/rating', :locals => { :asset => @course }
  end

部分“ ratings/_ rating.html.erb”:

  <div id="rating_div">
    <%= number_with_precision(asset.avg_rating, :precision => 1) %>/5 Stars<br>
    <ul>
      <li>
        <%= link_to_remote "1", {:url => { :controller => "ratings", :action => :create,  
            :rating => {:rateable_type => asset.class.to_s.downcase, :rateable_id => asset.id, :rating => 1}}},
            :method => :post, :class => 'one-star', :name => '1 star out of 5' %>
      </li>
      ...
    </ul>
  </div>

包含部分内容在主视图中这样:

<div 'star-ratings-block'>
   <%= render "ratings/rating", :locals => { :asset => yourvariablehere }  %>
</div>

它现在可以按需要工作了!

Found out how to solve it: I moved the "update" and "partial" parameters from the ratings partial to the Ratings > Create controller... Here is what it looks like now:

Ratings Controller: I changed the render options

  render :update do |page|
    page.replace_html  'star-ratings-block', :partial => 'ratings/rating', :locals => { :asset => @course }
  end

Partial "ratings/_rating.html.erb":

  <div id="rating_div">
    <%= number_with_precision(asset.avg_rating, :precision => 1) %>/5 Stars<br>
    <ul>
      <li>
        <%= link_to_remote "1", {:url => { :controller => "ratings", :action => :create,  
            :rating => {:rateable_type => asset.class.to_s.downcase, :rateable_id => asset.id, :rating => 1}}},
            :method => :post, :class => 'one-star', :name => '1 star out of 5' %>
      </li>
      ...
    </ul>
  </div>

The partial is included in the main view like that:

<div 'star-ratings-block'>
   <%= render "ratings/rating", :locals => { :asset => yourvariablehere }  %>
</div>

It now works as desired!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文