Rails 奇怪!rails c 可以执行,rails s 却卡住,不提交事务

davidwei · 2014年12月09日 · 最后由 billie66 回复于 2014年12月10日 · 3208 次阅读

最近在研究@happypeter的视频网站代码,自己写后台代码。不过在测试 tag 更新的时候出现了一个奇怪的问题。在更新 episode 的 tag 的时候,后台卡住,不提交事务。如果 Ctrl+C 关掉 Webrick 就会出现下图 Shut down 以下的内容,事务进行提交:

而用 rails c 跑一下,结果是可以提交:

请各位参谋一下。关键代码:

episode.rb

class Episode < ActiveRecord::Base
  has_many :taggings, dependent: :destroy
  has_many :tags, through: :taggings

...
def tag_names=(names)
  # 都处理为数组
    new_names = names.strip.split(';').map(&:strip)
    old_names = tag_names.split(';')
    self.tags = Tag.with_names(new_names, old_names)
  end

  def tag_names
    tags.map(&:name).join('; ')
  end
...
end

tag.rb

class Tag < ActiveRecord::Base
  has_many :taggings, dependent: :destroy
  has_many :episodes, through: :taggings

  def self.with_names(new_names, old_names)
    #only the added and shared names will return
    result = []
    added_names = new_names - old_names
    deleted_names = old_names - new_names
    shared_names = new_names & old_names

    #first, handle added_names
    added_names.each do |added_name|
      tag = Tag.find_by(name: added_name)
      if tag.present?
        tag.ep_count += 1
        tag.save
      else
        tag = Tag.create(name: added_name, ep_count: 1)
      end

      result << tag
    end

    #handle deleted_names
    deleted_names.each do |deleted_name|
      tag = Tag.find_by(name: deleted_name)
      if tag 
        tag.ep_count -= 1
        if tag.ep_count < 1 
          tag.destroy!
        else
          tag.save
        end
      end
    end

    #handle shared_names 
    shared_names.each do |shared_name|
      result << Tag.find_by(name: shared_name)
    end

    result 
  end

end

episodes_controller.rb

class EpisodesController < ApplicationController
.......
  def update
    respond_to do |format|
      if @episode.update(episode_params)
        format.html { redirect_to @episode, notice: 'Episode was successfully updated.' }
        format.json { render :show, status: :ok, location: @episode }
      else
        format.html { render :edit }
        format.json { render json: @episode.errors, status: :unprocessable_entity }
      end
    end
  end
.......
 private
    # Use callbacks to share common setup or constraints between actions.
    def set_episode
      @episode = Episode.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def episode_params
      params.require(:episode).permit(:name, :description, :revision, :published_at, :tag_names)
    end

再次对大家的帮助表示感谢。祝各位工作好心情。谢谢!

看看你的 episode_params,因为strong parameters?

#1 楼 @cqpx 已经补充了 episode_params。谢谢 如果是因为 strong_parameters,后台应该不会存在更新 tag 的操作,直接被 filter 了。^_^

@DavidWei 我在本地测试了一下 happycasts 的最新代码,没有复现你所描述的错误

5 楼 已删除

哈哈 我也研究过 happycast 的代码~ @billie66 @DavidWei

#3 楼 @billie66 哈哈,嫂子来了。多谢嫂子回复。我是自己用主分支代码作得参考。自己做了一些修改。这个是我本地的某些地方有问题。今天下午我也翻了下 railscasts-china 的关于 blog tag 的视频,我觉得我的思路也是对的。不过神奇的地方在于这个地方卡住了。我觉得 update 应该也不会出现这样的问题。 关键代码都在上面了。Orz

#5 楼 @zzz6519003 参考,学习,提高。哈哈

#6 楼 @DavidWei 看你研究 happycasts 的代码,感觉很荣幸。想帮忙找找错误,一看你把代码修改了一些,我也看不出哪儿出问题了。不知现在问题解决了没有

#5 楼 @zzz6519003 倍感荣幸,多多提意见,共同进步

需要 登录 后方可回复, 如果你还没有账号请 注册新账号