Search code examples
ruby-on-railsredmineredmine-plugins

Redmine: Custom filter field for adding News


I'd like to add a custom filter field to "Add News" page in Redmine, so that when I add a new news I could select group of users the email should be sent to.

The field itself is a list of Redmine User groups and every user is assigned to at least 1 of them.

Has anybody done this? Any suggestions would be appreciated

I've located the 3 files related to the issue:

  • /app/controller/news_controller.rb
  • /app/models/news.rb
  • /app/views/news/_form.html.erb
Environment:
  Redmine version                          2.2.1.stable.11156
  Ruby version                             1.8.7 (x86_64-linux)
  Rails version                            3.2.11
  Environment                              production
  Database adapter                         MySQL
Redmine plugins:
  no plugin installed

So far I've done only 1 modification in Redmine, which sends added news to all registered users. File: /app/modelsmailer.rb

Overview:

http://www.lwks.com/images/custom/redmine_question.png

EDIT: Following your advice I moved mailer function to the controller:

  def create
    @news = News.new(:project => @project, :author => User.current)
    @news.safe_attributes = params[:news]
    @news.save_attachments(params[:attachments])

    if @news.save
      #news_added(@news)
      if params[:group]
        mail :to => GroupsUser.find(params[:group][:ids]).joins(:users).select("users.mail").compact,
            :subject => "[#{@news.project.name}] #{l(:label_news)}: #{@news.title}"
      else
        render :new
      end
    end
  end

But I'm getting error: NameError (uninitialized constant NewsController::GroupsUser): pointing to line

mail :to => GroupsUser.find

Solution

  • news_controller.rb:

    def new
      @news = News.new
      @groups = GroupsUser.all
    end
    

    news/_form.html.erb:

    <%= label_tag :group_ids "Groups"
    <%= collection_select :group, :ids, @groups, :id, :name, {}, multiple: true %>
    

    Edit:

    I'm going to have to take a few guesses on what your controllers look like, but I'll give you something close. Based on the mailer function you provided, I'm assuming that was called out of the create controller after the News was saved. I would call the mail function after that. Something like this:

    def create
      news = News.new(params[:news]
      if news.save
        news_added(news)
        send_mail_to_groups(params[:group][:ids]) if params[:group]
        redirect_to ...
      else
        render :new
      end
    end
    

    The mailing part should be removed from news_added

    def news_added(news)
      redmine_headers 'Project' => news.project.identifier
      @author = news.author
      message_id news
      @news = news
      @news_url = url_for(:controller => 'news', :action => 'show', :id => news)
    end
    

    in favor of its own new routine:

    send_mail_to_users_by_group_ids(group_ids)
        # Woo: Sent to all users, despite their email settings
        mail :to => GroupsUser.find(group_ids).joins(:users).select("users.mail").compact,
          :subject => "[#{@news.project.name}] #{l(:label_news)}: #{@news.title}"
    end
    

    You might want to add a where clause to only include active users.

    I think that's about right. I'm doing it off the top of my head so there's probably a typo or error or two in there. Hopefully it points you in the right direction though.