我为Devise设置了以下vanilla重置密码邮件程序。这使得重置密码邮件在开发中具有正确的URL,但是在生产中抛出了错误
undefined local variable or method 'controller' for #<ResetPasswordMailer:0x00000007248f68>
看起来帮助程序的加载速度很好,但生成的路径只在生产中出现问题。
部分堆栈跟踪:
actionview (4.1.1) lib/action_view/routing_url_for.rb:99:in `_routes_context'
actionpack (4.1.1) lib/action_dispatch/routing/route_set.rb:372:in `block (2 levels) in define_mounted_helper'
actionpack (4.1.1) lib/action_dispatch/routing/route_set.rb:378:in `main_app'
devise (3.5.1) lib/devise/controllers/url_helpers.rb:63:in `_devise_route_context'
devise (3.5.1) lib/devise/controllers/url_helpers.rb:50:in `block (4 levels) in generate_helpers!'
app/mailers/reset_password_mailer.rb:7:in `reset_password_instructions'
源文件:
# app\mailers\reset_password_mailer.rb
class ResetPasswordMailer < Devise::Mailer
end
# app\views\devise\mailer\reset_password_instructions.html.erb
<p>Hello <%= @resource.email %>!</p>
<p>Someone has requested a link to change your password. You can do this through the link below.</p>
<p><%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %></p>
<p>If you didn't request this, please ignore this email.</p>
<p>Your password won't change until you access the link above and create a new one.</p>
更新
这是由config.eager_load = true
中的production.rb
设置引起的。将其更改为false
似乎不是最佳解决方案。
答案 0 :(得分:0)
试试这个package com.example.demo;
public class MainActivity extends Activity implements OnClickListener {
DBHelper helper;
SQLiteDatabase db;
Button btnBegin,btnnext,btnredirect;
int count = 0;
int response = 0;
View previouslySelectedItem = null;
//Sub category Buttons
Button btnaptitude5,btnaptitude4,btnaptitude3,btnaptitude2,btnaptitude1;
String Question_ID,Title,TitleDescription,QuestionText,QuestionTemplate,QuestionImage;
//String SubModuleQuestion_ID;
TextView tvTitle,tvInstructions,tvQuestionText;
RadioGroup rgtemplate4images;
ImageView img;
RelativeLayout aptitudesubcateg,temp4optimage, redirecttemplate;
ListView listviewoptions;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.aptitude);
aptitudesubcateg = (RelativeLayout) findViewById(R.id.aptitudesubcateg);
temp4optimage = (RelativeLayout) findViewById(R.id.temp4optimage);
temp4optimage.setClickable(false);
redirecttemplate = (RelativeLayout) findViewById(R.id.redirecttemplate);
// int position = 1;
listviewoptions = (ListView)findViewById(R.id.listViewoptions);
listviewoptions.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1,int position ,
long arg3) {
//arg1.setBackgroundColor(getResources().getColor(
// R.color.pressed_color));
if (previouslySelectedItem != null)
{
previouslySelectedItem.setBackgroundColor(Color.TRANSPARENT);
//getResources().getColor(R.color.pressed_color));
}
arg1.setBackgroundColor(Color.WHITE);
// getResources().getColor(R.color.default_color));
previouslySelectedItem = arg1;
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(),String.valueOf(position+1), Toast. LENGTH_SHORT).show();
response = position+1;
}
});
aptitudesubcateg.setVisibility(View.GONE);
temp4optimage.setVisibility(View.GONE);
redirecttemplate.setVisibility(View.GONE);
btnaptitude1 = (Button)findViewById(R.id.btnaptitude1);
btnaptitude2 = (Button)findViewById(R.id.btnaptitude2);
btnaptitude3 = (Button)findViewById(R.id.btnaptitude3);
btnaptitude4 = (Button)findViewById(R.id.btnaptitude4);
btnaptitude5 = (Button)findViewById(R.id.btnaptitude5);
btnredirect = (Button)findViewById(R.id.btnredirect);
btnaptitude1.setOnClickListener(this);
btnaptitude2.setOnClickListener(this);
btnaptitude3.setOnClickListener(this);
btnaptitude4.setOnClickListener(this);
btnaptitude5.setOnClickListener(this);
btnredirect.setOnClickListener(this);
helper=new DBHelper(this);
//addQuestion();
btnBegin = (Button)findViewById(R.id.btnBeginAptitude);
btnBegin.setOnClickListener(this);
btnnext = (Button)findViewById(R.id.btnNxtTemp4optnsImg);
btnnext.setOnClickListener(this);
}
public void addQuestion()
{
{
// Add Record with help of ContentValues and DBHelper class object
ContentValues values = new ContentValues();
// values.put(DBHelper.Q_ID, "a");
values.put(DBHelper.Module_ID,"1");
values.put(DBHelper.SubModule_ID,"2");
values.put(DBHelper.Question_ID,"2" );
values.put(DBHelper.SubModuleQuestion_ID,"1");
values.put(DBHelper.Title,"Test");
values.put(DBHelper.TitleDescription, "Demo");
values.put(DBHelper.QuestionText, "I find it easy to discuss any topic with a new person");
values.put(DBHelper.QuestionImage, "user.png");
values.put(DBHelper.QuestionTemplate, "template4options.xml");
values.put(DBHelper.CorrectOptionID, "1");
// Call insert method of SQLiteDatabase Class and close after
// performing task
db = helper.getWritableDatabase();
db.insert(DBHelper.TableQuestionMaster, null, values);
db.close();
Toast.makeText(this, "Question Added Successfully",
Toast.LENGTH_LONG).show();
}
}
public int getcount(String moduleID, String SubModuleID)
{
count = 0;
String selectQuery = "Select * from TableQuestionMaster where Module_ID = "+moduleID+" AND SubModule_ID ="+SubModuleID;
SQLiteDatabase db = helper.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
count = cursor.getCount();
Toast.makeText(this, String.valueOf(count) ,Toast.LENGTH_LONG).show();
cursor.close();
db.close();
return count;
}
private void Getoptions() {
// database handler
DBHelper db = new DBHelper(getApplicationContext());
// Spinner Drop down elements
List<String> options = db.getAllOptions(Question_ID);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1, options);
listviewoptions.setAdapter(adapter);
//Toast.makeText(this,"",Toast.LENGTH_LONG).show();
}
public void getAllQuestionsAptitude(String moduleID, String SubModuleID,String SubModuleQuestion_ID){
SQLiteDatabase db = helper.getReadableDatabase();
Cursor c = null;
if (count>0)
{
// SubModuleQuestion_ID = "1";
String selectQuestion = "Select * from TableQuestionMaster where Module_ID = "+moduleID+" AND SubModule_ID ="+SubModuleID+" AND SubModuleQuestion_ID ="+SubModuleQuestion_ID;
c = db.rawQuery(selectQuestion, null);
if (c.moveToFirst()) {
do {
Question_ID = c.getString(c.getColumnIndex("Question_ID"));
Title = c.getString(c.getColumnIndex("Title"));
TitleDescription = c.getString(c.getColumnIndex("TitleDescription"));
QuestionText = c.getString(c.getColumnIndex("QuestionText"));
QuestionTemplate = c.getString(c.getColumnIndex("QuestionTemplate"));
QuestionImage = c.getString(c.getColumnIndex("QuestionImage"));
Toast.makeText(this,Question_ID+" "+Title+" "+TitleDescription+" "+QuestionText+" "+QuestionTemplate+" "+QuestionImage,Toast.LENGTH_LONG).show();
Getoptions();
} while (c.moveToNext());
}
}
else
{
Toast.makeText(this,"NO question to display",Toast.LENGTH_LONG).show();
}
// closing connection
c.close();
db.close();
}
public void displayquestions()
{
Toast.makeText(this,"count on display Q is"+ count,Toast.LENGTH_LONG).show();
if (count >0)
{
getAllQuestionsAptitude("1","2",String.valueOf(count));
aptitudesubcateg.setVisibility(View.GONE);
temp4optimage.setVisibility(View.VISIBLE);
tvTitle = (TextView)findViewById(R.id.tvTitleTemplate4optoinsImage);
tvInstructions = (TextView)findViewById(R.id.tvInstructionstemplate4);
tvQuestionText = (TextView)findViewById(R.id.tvQuestionTextTemplate4ImageAptitude);
img = (ImageView)findViewById(R.id.imageViewtemplate4optionsAptitude);
tvTitle.setText(Title);
tvInstructions.setText(TitleDescription);
tvQuestionText.setText(QuestionText);
String imgName = QuestionImage; // specify here your image name fetched from db
String uri = "drawable/" + imgName;
int icon = getResources().getIdentifier(uri, "drawable", getPackageName());
img.setImageResource(icon);
//NextQuestion();
}
else
{
aptitudesubcateg.setVisibility(View.GONE);
temp4optimage.setVisibility(View.GONE);
redirecttemplate.setVisibility(View.VISIBLE);
Toast.makeText(this,"NO question to display",Toast.LENGTH_LONG).show();
}
}
public void NextQuestion()
{
if (count>0)
{
count = count - 1;
saveQuestion();
}
else
{
aptitudesubcateg.setVisibility(View.GONE);
temp4optimage.setVisibility(View.GONE);
redirecttemplate.setVisibility(View.VISIBLE);
}
}
public void saveQuestion()
{
if (response != 0)
{
ContentValues values = new ContentValues();
// values.put(DBHelper.Q_ID, "a");
values.put(DBHelper.StudentID,"1" );
values.put(DBHelper.R_QuestionID,Question_ID);
values.put(DBHelper.QuestOptionID,String.valueOf(response));
db = helper.getWritableDatabase();
db.insert(DBHelper.TABLEResponse, null, values);
db.close();
Toast.makeText(this, "Response saved Successfully",
Toast.LENGTH_LONG).show();
displayquestions();
}
else
{
Toast.makeText(this, "Please Select an option",
Toast.LENGTH_LONG).show();
}
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (v==btnBegin)
{
aptitudesubcateg.setVisibility(View.VISIBLE);
temp4optimage.setVisibility(View.GONE);
}
if (v== btnaptitude1)
{
getcount("1", "1");
// displayquestions();
}
if (v== btnaptitude2)
{
getcount("1", "2");
displayquestions();
}
if (v== btnaptitude3)
{
getcount("1", "3");
// displayquestions();
}
if (v== btnaptitude4)
{
getcount("1", "4");
// displayquestions();
}
if (v== btnaptitude5)
{
getcount("1", "5");
// displayquestions();
}
if (v== btnnext)
{
NextQuestion();
}
if (v==btnredirect)
{
aptitudesubcateg.setVisibility(View.VISIBLE);
temp4optimage.setVisibility(View.GONE);
redirecttemplate.setVisibility(View.GONE);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/back" >
<TextView
android:id="@+id/tvInstructionsAptitude"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/tvQuestionTextTemplate4Image"
android:layout_alignParentTop="true"
android:layout_alignRight="@+id/TextView01"
android:layout_marginTop="93dp"
android:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam nibh ex, elementum non bibendum ac, consequat a sem. Proin aliquet arcu id lacus interdum, sed fermentum neque sollicitudin. Vestibulum mauris massa, vulputate tincidunt quam vel, egestas tincidunt nisi. Ut ut nulla sagittis, aliquet lectus vitae, pretium nisi. Duis maximus, magna vitae ultricies consectetur, ex felis congue turpis, id scelerisque nisl ex at turpis. Aenean dui sapien, euismod at sem non, rhoncus molestie urna. Mauris condimentum risus felis, nec iaculis orci accumsan nec. Vivamus pharetra ultricies quam a aliquam. Praesent facilisis turpis malesuada massa interdum consequat. In hac habitasse platea dictumst. Integer efficitur nibh risus, ac mattis mi porta ut. Nam leo ex, pulvinar eu orci vel, pretium maximus velit. Pellentesque rhoncus sapien felis, in cursus eros malesuada imperdiet."
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/tvQuestionTextTemplate4Image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="53dp"
android:layout_marginTop="40dp"
android:text="Instructions"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/tvQuestionTextTemplate4Image"
android:layout_alignBottom="@+id/tvQuestionTextTemplate4Image"
android:layout_alignParentRight="true"
android:layout_marginRight="36dp"
android:text="Time : 10 Mins"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Button
android:id="@+id/btnBeginAptitude"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/tvInstructionsAptitude"
android:layout_alignRight="@+id/tvInstructionsAptitude"
android:layout_below="@+id/tvInstructionsAptitude"
android:layout_marginTop="42dp"
android:text="Begin" />
<include
android:id="@+id/aptitudesubcateg"
android:layout_width="match_parent"
android:layout_height="match_parent"
layout="@layout/aptitudesubcategory" />
<include
android:id="@+id/temp4optimage"
android:layout_width="fill_parent"
android:layout_height="match_parent"
layout="@layout/template4optionsimage" />
<include
android:id="@+id/redirecttemplate"
android:layout_width="fill_parent"
android:layout_height="match_parent"
layout="@layout/redirecttoaptitudesubmodule" />
</RelativeLayout>
答案 1 :(得分:0)
问题是由Rails 4.1.2上的config.eager_load = true
引起的。升级到Rails 4.2.0后,它可以正常工作。