简体   繁体   中英

Rails 4: “wrong number of arguments (2 for 1)”

I know this is a pretty standard error, but I could not figure out a solution to this particular solution from other questions.

I am following this coderwall tutorial about Creating a Scoped Invitation System for Rails .

I have four models, as follows:

class User < ActiveRecord::Base
  has_many :administrations
  has_many :calendars, through: :administrations
  has_many :invitations, :class_name => "Invite", :foreign_key => 'recipient_id'
  has_many :sent_invites, :class_name => "Invite", :foreign_key => 'sender_id'
end

class Calendar < ActiveRecord::Base
  has_many :administrations
  has_many :users, through: :administrations
  has_many :invites
end

class Administration < ActiveRecord::Base
  belongs_to :user
  belongs_to :calendar
end

class Invite < ActiveRecord::Base
  belongs_to :calendar
  belongs_to :sender, :class_name => 'User'
  belongs_to :recipient, :class_name => 'User'
end

And this is the migration for the Invite model:

class CreateInvites < ActiveRecord::Migration
  def change
    create_table :invites do |t|
      t.string :email 
      t.integer :calendar_id
      t.integer :sender_id
      t.integer :recipient_id
      t.string :recipient_role
      t.string :token
      t.timestamps null: false
    end
  end
end

The goal of the Invite model is to allow User s to invite other User s to join a particular Calendar .

The create Invite form is embedded in the Calendar edit view, as follows:

<h2>Edit <%= @calendar.name %> calendar</h2>

<%= render 'form' %>

<h2>Invite new users to <%= @calendar.name %> calendar</h2>

<%= form_for @invite , :url => invites_path do |f| %>
    <%= f.hidden_field :calendar_id, :value => @invite.calendar_id %>
    <%= f.label :email %>
    <%= f.email_field :email %>
    <%= f.label "Role" %>
    <%= f.radio_button(:recipient_role, "Editor") %>
    <%= f.label "Editor" %>
    <%= f.radio_button(:recipient_role, "Viewer") %>
    <%= f.label "Viewer" %>
    <%= f.submit 'Send' %>
<% end %>

<%= link_to 'Show', calendar_path %> |
<%= link_to 'Back', calendars_path %>

Here is the corresponding Calendars#Edit :

def edit
  @user = current_user
  @invite = @calendar.invites.build
  authorize @calendar
end

And here is the InvitesController :

class InvitesController < ApplicationController
  def create
    @invite = Invite.new(invite_params) # Make a new Invite
    @invite.sender_id = current_user.id # set the sender to the current user
    if @invite.save
      InviteMailer.invite(@invite, new_user_registration_path(:invite_token => @invite.token)).deliver #send the invite data to our mailer to deliver the email
    else
      format.html { render :edit, notice: 'Invitation could not be sent.' }
    end
  end

  private

  def invite_params
    params.require(:invite).permit(:email)
  end

end

Last but not least, here is the InviteMailer :

class InviteMailer < ApplicationMailer

  def invite(invite)
    @link = new_user_registration_path invite_token: invite.token
    mail to: invite.email, subject: "Calendy Invitation"
  end

end

When I visit http://localhost:3000/calendars/3/edit and submit the Invite create form, I get the following error:

ArgumentError in InvitesController#create
wrong number of arguments (2 for 1)

class InviteMailer < ApplicationMailer

  def invite(invite)
    @link = new_user_registration_path invite_token: invite.token
    mail to: invite.email, subject: "Calendy Invitation"
  end

My instinct would be to replace:

InviteMailer.invite(@invite, new_user_registration_path(:invite_token => @invite.token)).deliver

With:

InviteMailer.invite(@invite).deliver

But I am not sure this is actually the right solution.

Any idea about how to fix this error?

May be changing the invite to allow an extra argument like below should work too

class InviteMailer < ApplicationMailer
  def invite(invite, link)
    @link = link
    mail to: invite.email, subject: "Calendy Invitation"
  end
end

My instinct would be to replace:

 InviteMailer.invite(@invite, new_user_registration_path(:invite_token => @invite.token)).deliver 

With:

 InviteMailer.invite(@invite).deliver 

Yes, that would be fine, since you're doing the same - your InviteMailer#invite stores this data itself in @link variable:

class InviteMailer < ApplicationMailer

  def invite(invite)
    @link = new_user_registration_path invite_token: invite.token
    mail to: invite.email, subject: "Calendy Invitation"
  end
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM