diff options
| author | Kir | 2011-10-31 16:16:45 +0400 | 
|---|---|---|
| committer | Kir | 2011-10-31 16:16:45 +0400 | 
| commit | 7a540a454e4b2c2ccac5f6e542fe5130dbd05c8f (patch) | |
| tree | ddab265d7f62493f0e84a3b7cfbef06b2112123d /app | |
| parent | a99eda077cd84e42bb526ffecc4bc59c4c1929de (diff) | |
| download | inboxes-7a540a454e4b2c2ccac5f6e542fe5130dbd05c8f.tar.bz2 | |
Readme and initial changes
Diffstat (limited to 'app')
| -rw-r--r-- | app/controllers/discussions_controller.rb | 84 | ||||
| -rw-r--r-- | app/models/discussion.rb | 118 | ||||
| -rw-r--r-- | app/models/message.rb | 22 | ||||
| -rw-r--r-- | app/models/speaker.rb | 17 | ||||
| -rw-r--r-- | app/views/discussions/_form.html.haml | 10 | ||||
| -rw-r--r-- | app/views/discussions/index.html.haml | 5 | ||||
| -rw-r--r-- | app/views/discussions/new.html.haml | 2 | ||||
| -rw-r--r-- | app/views/discussions/show.html.haml | 5 | 
8 files changed, 263 insertions, 0 deletions
| diff --git a/app/controllers/discussions_controller.rb b/app/controllers/discussions_controller.rb new file mode 100644 index 0000000..7d5d8ca --- /dev/null +++ b/app/controllers/discussions_controller.rb @@ -0,0 +1,84 @@ +class DiscussionsController < ApplicationController +  # load_and_authorize_resource +  # before_filter :load_and_check_discussion_recipient, :only => [:create, :new] +   +  def index +    # показываем дискуссии юзера, и те куда его присоеденили +    # так как имеем массив дискуссий, его пагинация будет через хак +    @discussions = current_user.discussions +     +    respond_to do |format| +      format.html # index.html.erb +      format.json { render :json => @discussions } +    end +  end + +  # GET /discussions/1 +  # GET /discussions/1.json +  def show +    @discussion = Discussion.includes(:messages, :speakers).find(params[:id]) +    # @discussion.mark_as_read_for(current_user) # сделаем прочтенной для пользователя +     +    # члены дискуссии - приглашенные в нее + ее создатель +    @message = Message.new + +    respond_to do |format| +      format.html # show.html.erb +      format.json { render :json => @discussion } +    end +  end + +  # GET /discussions/new +  # GET /discussions/new.json +  def new +    @discussion = Discussion.new +    @discussion.messages.build +  end +   +  # POST /discussions +  # POST /discussions.json +  def create +    @discussion = Discussion.new(params[:discussion]) +    @discussion.messages.each do |m| +      m.discussion = @discussion +      m.user = current_user +    end +    @discussion.add_recipient_token current_user.id +     +    respond_to do |format| +      if @discussion.save +        format.html { redirect_to @discussion, :notice => 'Дискуссия начата.' } +    #     format.json { render :json => @discussion, :status => :created, :location => @discussion } +      else +        format.html { render :action => "new" } +    #     format.json { render :json => @discussion.errors, :status => :unprocessable_entity } +      end +    end +  end +   +  def leave +    @discussion.remove_speaker(current_user) +    redirect_to discussions_url, :notice => "Вы успешно покинули дискуссию." +  end +   +  private +   +  def load_and_check_discussion_recipient +    @discussion.recipient_tokens = params[:recipients] if params[:recipients] +     +    # проверка, существует ли уже дискуссия с этим человеком +    if @discussion.recipient_ids && @discussion.recipient_ids.size == 1 +      user = User.find(@discussion.recipient_ids.first) +      discussion = Discussion.find_between_users(current_user, user) +      if discussion +        # дискуссия уже существует, добавим в нее написанное сообщение +        @discussion.messages.each do |m| +          Message.create!(:discussion => discussion, :user => current_user, :body => m.body) if m.body +        end +        # перекидываем на нее +        redirect_to discussion_url(discussion), :notice => "Переписка между вами уже существует." +      end +    end +     +  end +end diff --git a/app/models/discussion.rb b/app/models/discussion.rb new file mode 100644 index 0000000..474ad00 --- /dev/null +++ b/app/models/discussion.rb @@ -0,0 +1,118 @@ + +class Discussion < ActiveRecord::Base +  attr_accessor :recipient_tokens, :recipient_ids +  attr_reader :recipient_ids + +  # paginates_per 10 + +  # создатель +  has_many :messages, :dependent => :destroy + +  # участники +  has_many :speakers, :dependent => :destroy +  has_many :users, :through => :speakers + +  # отметки о прочтении юзеров +  # has_many :views, :dependent => :destroy, :class_name => "DiscussionView" + +  # жутко неоптимизированная часть, возможны баги +  # scope :unread_for, lambda { |user_or_user_id| joins(:views, :speakers).where("discussions.updated_at >= discussion_views.updated_at AND speakers.user_id = ?", user_or_user_id.is_a?(User) ? user_or_user_id.id : user_or_user_id ) } + +  accepts_nested_attributes_for :messages + +  validate :check_that_has_at_least_two_users # не даем создать дискуссию, у которой нет получателей + +  # добавляем записи об указанных собеседников +  after_save(:on => :create) do +    Rails.logger.info("Repicients ids: #{recipient_ids.inspect}") + +    if recipient_ids.kind_of?(Array) +      recipient_ids.uniq! +      recipient_ids.each do |id| +        recipient = User.find(id) +        add_speaker(recipient) if recipient +      end +    end +  end + +  def recipient_tokens=(ids) +    self.recipient_ids = ids +  end + +  def add_recipient_token id +    self.recipient_ids << id if self.recipient_ids +  end + +  def add_speaker(user) +    raise ArgumentError, "You can add speaker only to existing Discussion. Save your the Discussion object firstly" if new_record? +    Speaker.create(:discussion => self, :user => user) +  end + +  def remove_speaker(user) +    speaker = find_speaker_by_user(user) +    speaker.destroy if speaker +  end + +  def user_invited_at(user) +    speaker = find_speaker_by_user(user) +    speaker.created_at +  end + +  def can_participate?(user) +    speaker = find_speaker_by_user(user) +    speaker ? true : false +  end + +  # проверяет, есть ли уже беседа между пользователями +  # TODO вынести в отдельный метод а в этом возращать true/false, а то неправославно как-то +  def self.find_between_users(user, user2) +    res = nil +    discussions = self.joins(:speakers).includes(:users).where("speakers.user_id = ?", user.id) +    Rails.logger.info "Searching for ids: #{user.id}, #{user2.id}" +    discussions.each do |discussion| + +      res = discussion if discussion.private? && ((discussion.users.first == user && discussion.users.last == user2) || (discussion.users.first == user2 && discussion.users.last == user)) +      Rails.logger.info "Searching for ids: #{discussion.users.inspect}" if discussion.private? +    end +    res +  end + +  # приватная/групповая +  def private? +    self.users.size <= 2 +  end + +  # дата последнего сообщения в дискуссии +  def last_message_at +    self.messages.last ? self.messages.last.created_at : nil +  end + +  # проверка, является ли дискуссия непрочитанной для пользователя +  # def unread_for?(user) +  #   flag = self.views.find_by_user_id(user.id) +  #   if flag +  #     self.updated_at >= flag.updated_at +  #   else +  #     true +  #   end +  # end + +  # пометить как прочитанная +  def mark_as_read_for(user) +    true +  #   flag = DiscussionView.find_or_create_by_user_id_and_discussion_id(user.id, self.id) +  #   flag.touch +  end + +  private + +  def find_speaker_by_user user +    Speaker.find_by_discussion_id_and_user_id!(self.id, user.id) +  end + +  def check_that_has_at_least_two_users +    Rails.logger.info self.recipient_ids +    errors.add :recipient_tokens, "Укажите хотя бы одного получателя" #if !self.recipient_ids || self.recipient_ids.size < 2 +  end + +end
\ No newline at end of file diff --git a/app/models/message.rb b/app/models/message.rb new file mode 100644 index 0000000..a38dfb0 --- /dev/null +++ b/app/models/message.rb @@ -0,0 +1,22 @@ +class Message < ActiveRecord::Base + +  default_scope order(:created_at) +   +  belongs_to :discussion, :counter_cache => true +  belongs_to :user +   +  validates :user, :discussion, :body, :presence => true +   +  # after_save :touch_discussion_and_mark_as_read +   +  # def visible_for? user +  #   self.created_at.to_i >= self.discussion.user_invited_at(user).to_i +  # end +   +  private +   +  def touch_discussion_and_mark_as_read +    self.discussion.touch +    # self.discussion.mark_as_read_for(self.user) +  end +end diff --git a/app/models/speaker.rb b/app/models/speaker.rb new file mode 100644 index 0000000..6105220 --- /dev/null +++ b/app/models/speaker.rb @@ -0,0 +1,17 @@ +class Speaker < ActiveRecord::Base +  belongs_to :user +  belongs_to :discussion +   +  validates_uniqueness_of :user_id, :scope => :discussion_id +  validates :user, :discussion, :presence => true +   +  after_destroy :destroy_discussion_view +   +  private +   +  def destroy_discussion_view +    @view = DiscussionView.find_by_user_id_and_discussion_id(self.user_id, self.discussion_id) +    @view.destroy if @view +  end +   +end diff --git a/app/views/discussions/_form.html.haml b/app/views/discussions/_form.html.haml new file mode 100644 index 0000000..52da4a6 --- /dev/null +++ b/app/views/discussions/_form.html.haml @@ -0,0 +1,10 @@ += form_for @discussion do |f| +  .entry +    = f.label :recipient_tokens +    = f.collection_select :recipient_tokens, User.all, :id, :name, :prompt => true, :html_options => { :multiple => true } +  .entry +    = f.fields_for :messages do |j| +      = j.label :body +      = j.text_area :body, :label => "Сообщение" +   +  = f.submit 'Отправить'
\ No newline at end of file diff --git a/app/views/discussions/index.html.haml b/app/views/discussions/index.html.haml new file mode 100644 index 0000000..669c01b --- /dev/null +++ b/app/views/discussions/index.html.haml @@ -0,0 +1,5 @@ +%h3 Discussions +- @discussions.each do |discussion| +  = discussion.id +   += link_to "Create new", new_discussion_path
\ No newline at end of file diff --git a/app/views/discussions/new.html.haml b/app/views/discussions/new.html.haml new file mode 100644 index 0000000..3f68ec9 --- /dev/null +++ b/app/views/discussions/new.html.haml @@ -0,0 +1,2 @@ +%h3 New discussion += render "form"
\ No newline at end of file diff --git a/app/views/discussions/show.html.haml b/app/views/discussions/show.html.haml new file mode 100644 index 0000000..8c13728 --- /dev/null +++ b/app/views/discussions/show.html.haml @@ -0,0 +1,5 @@ += @discussion.users.map { |u| u.name }.join(", ") += debug @discussion.speakers  + +- @discussion.messages.each do |message| +  = message.body
\ No newline at end of file | 
