Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Offer the option to use parameterization for shared processing of headers and ivars#27825

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
dhh merged 9 commits intomasterfromparameterized-mailers
Jan 28, 2017

Conversation

@dhh
Copy link
Member

@dhhdhh commentedJan 27, 2017
edited
Loading

Consider this example that does not use parameterization:

classInvitationsMailer <ApplicationMailerdefaccount_invitation(inviter,invitee)@account=inviter.account@inviter=inviter@invitee=inviteesubject="#{@inviter.name} invited you to their Basecamp (#{@account.name})"mail \subject:subject,to:invitee.email_address,from:common_address(inviter),reply_to:inviter.email_address_with_nameenddefproject_invitation(project,inviter,invitee)@account=inviter.account@project=project@inviter=inviter@invitee=invitee@summarizer=ProjectInvitationSummarizer.new(@project.bucket)subject="#{@inviter.name.familiar} added you to a project in Basecamp (#{@account.name})"mail \subject:subject,to:invitee.email_address,from:common_address(inviter),reply_to:inviter.email_address_with_nameenddefbulk_project_invitation(projects,inviter,invitee)@account=inviter.account@projects=projects.sort_by(&:name)@inviter=inviter@invitee=inviteesubject="#{@inviter.name.familiar} added you to some new stuff in Basecamp (#{@account.name})"mail \subject:subject,to:invitee.email_address,from:common_address(inviter),reply_to:inviter.email_address_with_nameendendInvitationsMailer.account_invitation('david@basecamp.com','jason@basecamp.com').deliver_later

Using parameterized mailers, this can be rewritten as:

classInvitationsMailer <ApplicationMailerbefore_action{@inviter,@invitee=params[:inviter],params[:invitee]}before_action{@account=params[:inviter].account}defaultto:->{@invitee.email_address},from:->{common_address(@inviter)},reply_to:->{@inviter.email_address_with_name}defaccount_invitationmailsubject:"#{@inviter.name} invited you to their Basecamp (#{@account.name})"enddefproject_invitation@project=params[:project]@summarizer=ProjectInvitationSummarizer.new(@project.bucket)mailsubject:"#{@inviter.name.familiar} added you to a project in Basecamp (#{@account.name})"enddefbulk_project_invitation@projects=params[:projects].sort_by(&:name)mailsubject:"#{@inviter.name.familiar} added you to some new stuff in Basecamp (#{@account.name})"endendInvitationsMailer.params(inviter:'david@basecamp.com',invitee:'jason@basecamp.com').account_invitation.deliver_later

That's a big improvement! It's also fully backwards compatible. So you can start to gradually transition
mailers that stand to benefit the most from parameterization one by one and leave the others behind.

brunowego, fbbergamo, p1366, ecleel, and cristianrennella reacted with thumbs up emojigeorgeclaghorn, kaspth, cycomachead, fahrenq, adammiribyan, nzaillian, mustela, EtienneDepaulis, Bahanix, glaucocustodio, and 15 more reacted with heart emoji
@@ -0,0 +1,141 @@
module ActionMailer
# Provides the option to parameterize mailers in other to share ivar setup, processing, and common headers.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

"in other" -> "in order"

joshuapinter reacted with thumbs up emoji
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I'd also expandinstance variable.

joshuapinter reacted with thumbs up emoji
@kaspth
Copy link
Contributor

kaspth commentedJan 27, 2017
edited
Loading

Digging it, especially now that we can extract things intodefault 👍

I'm curious why the method is calledparams? Is it to bridge the terminology gap between controllers and mailers? I'm asking because I'd have thought this would be calledassigns, which eludes to the view aspects of mailers.

Especially since most of the mailer actions I've written just blankly assign their parameters to an instance variable so I'm curious if we should take this a step further with:

classInvitationsMailer <ApplicationMailerassigns:inviter,:inviteeassigns(:account){@inviter.account}# Personally, meh. But throwing it out there :)end

This would then just do@inviter = assigns[:inviter].

In case a specific action haven't passed, say,:invitee, the action would just have a blank@invitee ivar and nothing would blow up.

This way I think we could also avoid theparams method while keeping backwardscompatibility:

InvitationsMailer.account_invitation(inviter:'david@basecamp.com',invitee:'jason@basecamp.com').deliver_later

RegardingProc.new indefault. It feels outside of the Rails aesthetic to me and I'm curious if we should do something to support:

defaultto:->{@invitee.email_address}

Or if we're cool enough withproc :)

Copy link
Contributor

@kaspthkaspth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Implementation seems fine 👍

@kaspth
Copy link
Contributor

Reading your example again, we'd probably need to update:

InvitationsMailer.account_invitation(inviter:'david@basecamp.com',invitee:'jason@basecamp.com').deliver_later

Since those strings won't respond toaccount,name etc. 😁

Copy link
Contributor

@maclover7maclover7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

IMHO, I don't see this as a big improvement over the current usage. Introducing aActionMailer::Base#params method which you then call the mailer method on seems kind of messy to me. I'm a big fan of explicitly passing arguments to the mailer method, over more magicalparams handling 😬

@dhh
Copy link
MemberAuthor

dhh commentedJan 28, 2017 via email

There's nothing magical about setting a context which allows controller-wide preprocessing. That's exactly how action controllers work, and this brings mailers in line with that usage.The A/B here is imo undeniable, and it's a reduced example from what I've actually seen in Basecamp code. There the advantage is even larger.As a general observation, I find any objections based on the idea of "magic" entirely without persuasion. Especially in this case where the flow basically is "instantiate object, assign variables, call method". It doesn't get more basic OO than that.
On Jan 27, 2017, at 21:38, Jon Moss ***@***.***> wrote:@maclover7 commented on this pull request. IMHO, I don't see this as a big improvement over the current usage. Introducing a ActionMailer::Base#params method which you then call the mailer method on seems kind of messy to me. I'm a big fan of explicitly passing arguments to the mailer method, over more magical params handling 😬 — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

@dhh
Copy link
MemberAuthor

dhh commentedJan 28, 2017 via email

Params was just to match the concept from controllers in the sense that they're going to be used the same way. Especially as it relates to serialization during jobs as well.#assigns is not a bad way to go either though, but I don't think it has the same overall naming benefits. Here we can now talk of a new concept: parameterized mailers. The method follows that name. And it makes the before_action and other filters feel immediately familiar to anyone who've done the same work with action controllers.Agree on the Procs. I didn't change anything there, that's just the implementation AM already had. It only took Procs, not lambdas. If you want to have a look at that, please do!I looked at the assigns thing at the top level too. Kinda like expose. But I couldn't find enough value in my code to justify the new concept.
On Jan 27, 2017, at 19:06, Kasper Timm Hansen ***@***.***> wrote: Digging it, especially now that we can extract things into default 👍 I'm curious why the method is calledparams? Is it to bridge the terminology gap between controllers and mailers? I'm asking because I'd have thought this would be called assigns, which eludes to the view aspects of mailers. Especially since most of the mailer actions I've written just blankly assign their parameters to an instance variable so I'm curious if we should take this a step further with: class InvitationsMailer < ApplicationMailer assigns :inviter, :invitee assigns(:account) { @inviter.account } # Personally, meh. But throwing it out there :) end This would then just do@Inviter = assigns[:inviter]. In case a specific action haven't passed, say, :invitee, the action would just have a blank@invitee ivar and nothing would blow up. Regarding Proc.new in default. It feels outside of the Rails aesthetic to me and I'm curious if we should do something to support: default to: -> { @invitee.email_address } Or if we're cool enough with proc :) — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.
kaspth and Startouf reacted with thumbs up emoji

David Heinemeier Hanssonand others added8 commitsJanuary 28, 2017 10:20
Confusing to have both the context setter as a unqualified method andthe accessor as well. Considered #with_params, but I think that’simplied well enough using just #with.
Inviting yourself? Your life must be a party! 😄
@dhhdhh merged commit1cec84a intomasterJan 28, 2017
@dhhdhh deleted the parameterized-mailers branchJanuary 28, 2017 10:20
@kaspth
Copy link
Contributor

Here we can now talk of a new concept: parameterized mailers. The method follows that name. And it makes the before_action and other filters feel immediately familiar to anyone who've done the same work with action controllers.

Ha! It took me until now to fully grasp what you meant by this.params allows for better use ofbefore_action in Mailers and perfectly mirrors Action Controller's API of the same 😄

@rafaelfranca
Copy link
Member

This is great! I did some improvements in the implementation here341fab8...2dadf73

@kaspth
Copy link
Contributor

@rafaelfranca and now it's even better 😃🎉

@dhh
Copy link
MemberAuthor

dhh commentedJan 31, 2017

Lovely, thanks@rafaelfranca!

@williamromero
Copy link

Excuse me if i don't understand, but it means now we can send mails with a particular name for each mail for our mailing lists? Right? Sorry if don't understand it well.

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

3 more reviewers

@kaspthkaspthkaspth approved these changes

@maclover7maclover7maclover7 left review comments

@alexcameron89alexcameron89alexcameron89 left review comments

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

7 participants

@dhh@kaspth@rafaelfranca@williamromero@maclover7@alexcameron89

[8]ページ先頭

©2009-2025 Movatter.jp