Beginner's routing question: Redirecting to a different controller

I have a problem passing control from one controller to the next. Here
are the details:

I have a model ‘Dict’ with primary key :dictname. I have two
controllers, named ‘Login’ and ‘Dict’. The application starts in
views/login/index.html.erb, where I have - among other stuff - an entry
field for the dictname. When clicking a button, control passes to a
method in login_controller.rb, where various authentification is being
performed.

If all checks pass, control should now be transfered to a page
views/dict/manage.html.erb , and this page should receive the dictname
as a parameter.

Here is what I have tried so far:

In routes.rb I placed an entry

get 'dict/:id/manage', to: 'dict#manage'

In login_controller.rb, I tried to transfer the controll with

redirect_to dict_path(@dict)

However, I get the error message

'undefined method dict_path'

I thought that dict_path should be a helper method, which is generated
out of my routes.rb . Since this method is undefined, I suspect that my
routes.rb is not correct.

Note that I did NOT place a

resources :dicts

into routes.rb, because - for the time being - I don’t need yet the full
set of CRUD capabilities on a Dict, so I thought I’ll just start with
the minimum needed, and extend over the time as necessary. If you think
that this is an unwise decision, please let me know.

On May 23, 2014, at 7:04 AM, Ronald F. [email protected]
wrote:

into routes.rb, because - for the time being - I don’t need yet the full
set of CRUD capabilities on a Dict, so I thought I’ll just start with
the minimum needed, and extend over the time as necessary. If you think
that this is an unwise decision, please let me know.

Starting with the minimum you need now and building up is a good idea.
BUT you can go ahead and put the resource in the routes if you want. The
result of this is that an attempt to access an unimplemented action will
simply give you a different error message. (Or you can go ahead and stub
in a simple action that just renders a better error.)

get ‘dict/:id/manage’, to: ‘dict#manage’ , as: :dict

пятница, 23 мая 2014 г., 17:05:36 UTC+4 пользователь Ruby-Forum.com User
написал:

On Friday, May 23, 2014 9:09:20 AM UTC-4, Scott R. wrote:

you can go ahead and put the resource in the routes if you want. The result

I agree with everything Scott says in his post. This is a small point,
but
I don’t like having routes defined that aren’t really used. It’s a
small
point, because my solution is also going to lead to a different error,
but
I prefer to head things off at the source. I would use resources, as
Scott
suggests, but limit the actions that you really need such as:

resources :dicts, only: [:show]

resources :dicts, only: [:show, :index]

you get the idea. you can then relax the restrictions as you build out
the
functionality.

On May 23, 2014, at 8:03 AM, mike2r [email protected] wrote:

I agree with everything Scott says in his post. This is a small point, but I
don’t like having routes defined that aren’t really used. It’s a small point,
because my solution is also going to lead to a different error, but I prefer to
head things off at the source. I would use resources, as Scott suggests, but
limit the actions that you really need such as:

Very good point. My thinking was colored by the fact that I really only
do this during development, where I expect to implement the rest of the
actions very soon.

Евгений Шурмин wrote in post #1146886:

get ‘dict/:id/manage’, to: ‘dict#manage’ , as: :dict

Could you please kindly explain, what the effect of the “as: :dict” is
in this case? I understood that I need the “as:” parameter for those
cases where I want to name the route differently, but in this case, it
is always ‘dict’.

With other words: What would be the effect if I just leave out “as:
:dict”?

mike2r wrote in post #1146887:

I would use resources, as
Scott
suggests, but limit the actions that you really need such as:

resources :dicts, only: [:show]

Now in my case, the action has a “non-standard” name, i.e. “:manage”.

Can I use this too in the “only:” array, or should I instead use a
standard action (in this case probably “edit”), which then, inside my
controller, invokes the “manage” method?

From my understanding of the “Rails Routing From The Outside” guide,
routes.rb defines which controller methods are invoked, when a certain
request arrives, and the “resources” definition just creates standard
routes with standard action names for the “common case”
(show/index/edit/…). Did I grasp this correctly?

If I understood this right, I would have two possibilities: Use ab
action name which reflects the purpose of the action (here: ‘manage’)
and write a special route definition, as Евгений Шурмин suggested above,
or use the standard action names, and use a ‘resources’ definition. From
a viewpoint of maintainability, what would you consider the better
solution?

On Sunday, May 25, 2014 2:31:33 AM UTC-4, Ruby-Forum.com User wrote:

Can I use this too in the “only:” array, or should I instead use a
action name which reflects the purpose of the action (here: ‘manage’)
and write a special route definition, as Евгений Шурмин suggested above,
or use the standard action names, and use a ‘resources’ definition. From
a viewpoint of maintainability, what would you consider the better
solution?


Posted via http://www.ruby-forum.com/.

To answer your first question, when a segment key is part of your route
(:id) you need to tell rails what you want the named route to look like
or
it won’t generate one. Even if you didn’t have the segment key, for
example:

get ‘dict/manage’ => ‘dict#manage’

it would generate the named routes dict_manage_path and dict_manage_url
which isn’t what you want. Therefore, you need the as: :dict to
generate
the named route you are after.

In answer to your second question, yes, you have grasped the basics
correctly and yes. The resources statement creates the standard routes
as
well as the named routes to go with them. However, it’s part of a
larger
architecture of handling REST transactions. When you use the following:

rails generate scaffold dict

it will generate not only the routes statement, but the standard actions
and views to go with it. If you stick to the rails convention, it will
save you a lot of time and work, and I advise that you do so unless
there
is functionality that just won’t work with that structure.

I would argue that from your description (i’m at a little bit of a loss
since I haven’t actually seen your controller code), dict is a resource,
even if you don’t intend to initially offer users full CRUD options on
the
resource. Therefore, I prefer setting this up in the routes (and
elsewhere) as a resource and using standard Rails action names. The
word
“manage” to me could be adding a new entry to dict, modifying an
existing
entry, etc. This actually involves a number of actions and it would be
better to more specific about the purpose of each action. By the way,
edit
actually involves two actions. The first is to provide the user with a
form populated with the values of the existing entry to be edited. The
second happens when the user makes changes and submits the form, and the
resource is updated. In the Rails architecture, these are the edit and
update actions respectively and you would need to allow both in your
resources statement.

If you don’t like the Rails standard names for your routes, you can
change
them, although I still maintain it’s better to learn the Rails way of
doing
things and stick to it when possible. This makes maintenance and
integration with other parts of your application much easier. However,
in
this case, let’s assume we want to say manage instead of edit. You
would
route as follows:

resources: :dicts, path_names: { edit: ‘manage’ }

Note: this changes the path name, so you will have /dicts/:id/manage,
but
it doesn’t change the controller actions, it will still map to the
action
edit in the controller. Usually this is only done when there are
specific
reasons to do so, such as creating a site in a different language where
you
want the URL’s to reflect a language other than English.

On Sunday, May 25, 2014 1:40:40 PM UTC-4, Ruby-Forum.com User wrote:

with the application, and that’s why I invented the action “manage” in
controller". Do you recommend me to investigate into “generate scaffold”
parameters (such as path_names:) and examples of usage. Right now, when
I really want to know how something is done in Rails, I google for it,
hoping that someone else had the same problem. This often works out, but
I would be more happy if I had a documentation of the Rails classes and
methods, in a similar way as it is for Ruby and the standard functions
and -classes. Is this available, or is Rails in the flux so much that we
can’t expect this yet?


Posted via http://www.ruby-forum.com/.

OK, this gives me some more information, but I’m still not completely
sure
I understand the application. It sounds like a given user can have one
(or
more?) dictionaries associated with the user and that each dictionary
has
one or (probably) many idioms associated with it. In this case, dict is
a
resource. If I read this right, in your initial application a user
could
create a dictionary. I’m assuming that you may, in later development,
have
the option to edit a dictionary (which is different from editing an
idiom),
or delete a dictionary. However, you also have elements such as import
and
export that are not standard CRUD actions. You’ve included them in an
action manage, but I have a feeling that import and export may be also
be
separate actions. I’m making some assumptions here which I frequently
have
to do when answering posts on this list, and if I’ve assumed
incorrectly,
that will affect my answer.

In that case, you would need to extend the resource to include actions
in
addition to the standard new, create, edit, update, show, index, and
destroy actions. In this case, let’s assume we want to add the action
manage. You would do that as follows:

resources :dicts do
member do
get :manage
end
end

This differs from path_names. path_names changes the name of the path
but
does not otherwise affect the routing or actions associated with the
resource. The above code adds manage as a separate action, and creates
the
appropriate routing and named paths to go with it.

With respect to the scaffold generator, yes, I believe it is worth
using,
but there are developers that would disagree and don’t use it. Some of
the
tutorials, such as the railstutorial.org tutorial that is commonly
referenced on this list, have you use the controller generator and model
generator so that you learn the concepts involved by being forced to
manually create a lot of the elements. I believe this is appropriate
and a
good approach for a tutorial. Likewise, the same tutorial takes you
through the steps of manually creating a user resource and
authentication.
Again, you should, IMO, understand these concepts. However, there are
are
some ways to make your development more efficient once you have mastered
these concepts. The scaffold is one of them. Typically, I start with a
scaffold and generally modify it to fit the particular needs of that
resource. Likewise, I don’t usually (never) roll my own authentication,
I
use the Devise gem.

With respect to documentation, it is true, Rails changes quickly (IMO,
mostly for the better) and sometimes the documentation will lag a bit.
I
believe, in general, the Edge Guides are well done and would recommend
them. There are a few cases where they may not be as comprehensive as
you
might need. There is one other resource I would recommend. The Rails
4
Way
is a book you can buy from leanpub.com. I don’t have any
connection
to the book or that site, but if you buy it from them, you automatically
get any updates to the book and they update fairly regularly. This is,
IMO, an excellent reference. I would not use it to learn Rails basics.
It’s fairly advanced and would not be appropriate until you have
mastered
the basics through a tutorial, but it covers the topics you asked about
better than any other resource I know of. Hopefully, others have some
input here as I’m sure there are resources I’m not aware of. The
Railscasts are also good, but I’m not sure if they’re being maintained
and
updated at the moment.

The classes and methods themselves are documented in the Rails API
(api.rubyonrails.org). For example, at
api.rubyonrails.org/classes/ActionView/Helpers/Urlhelper.html you will
see
all the methods and options for button_to, link_to, mail_to, etc. that
you
use in view rendering.

You did grasp the concept of my application amazingly well, only that
the only possible ways to “edit” a dict is to add and remove idioms
(would you see this as editing the dictionary, or as manipulating the
Idiom class?).

The reason why I did not follow the CRUD way - and maybe this I was
mislead here - was the following:

When starting the design, I started with a concept of the screens the
user is going to see. The initial screen will present an entry form for
the name of the dictionary, the user name, buttons for creating and
opening a dictionary, and - for the creation case - an entry field
denoting a dictionary type (think about it as the “language” for the
dictionary, but the concept is more general).

After clicking one of the buttons, a new screen appears from where the
user can click various buttons - exporting the dictionary, start one of
three predefined training types, manually adding idioms to the
dictionary (but on this screen no possibility of deleting or editing
idioms, nor for the deletion of the dictionary).

My idea was that the logic for each web page should correspond to one
controller method. In this case, I have used two different controllers:
For the entry page I have a login_controller (because I would like to
add password authentification later on), and for the second form I have
a dict_controller.

Similarily, I am planning a training_controller for doing the idiom
training, and another controller (maybe idiom_controller) for adding,
deleting and editing individual idioms.

Maybe this mapping “web page” to “controller” is, from the onset, bad
design?

Thanks a lot for the detailed explanations. Two remarks for this:

As for the naming, my application evolves a dictionary of foreign
language idioms, and the main purpose it to train the user in the usage
of these idioms. From the perspective of the user, there are 3 types of
“screens” (HTML pages):

  • The login page (where he identifies himself, chooses (or create) a
    dictionary)

  • The Management page (where he can import/export dictionaries to/from
    database, merge other dictionaries into the existing ones, add new
    idioms (this is really an “edit” action) and, most important of all,
    select one of several training plans and start trainig).

  • The Training page, where an idiom training is performed on the fly.
    This page also allows, for convenience, editing vocabulary on the fly
    (but only the one which is presented right now).

From this setup, I found that the usual CRUD actions don’t go that well
with the application, and that’s why I invented the action “manage” in
dict, and in the meanwhile the action “start” in the (new)
training_controller. However I am flexible with names, and if an
experienced Rails developer strongly suggests going with standard action
names, I certainly don’t object. After all, I can still keep the “meat”
of my code in my “manage” routine, and just have the “edit” method call
“manage()”.

As for “generate scaffold”, I have used this when doing exercises back
with good old Rails 1, but now with Rails 4, the tutorial doesn’t use
“generate scaffold” anymore, but always “generate model” and “generate
controller”. Do you recommend me to investigate into “generate scaffold”
too?

Thanks a lot for your detailed comment. It really helps a lot!

One final question: I have read various tutorials, but when it comes to
look up the API, I found the documentation a bit confusing, and
difficult to find what I am looking for. You gave for example a
suggestion to use the “resources” method with the path_names: parameter.
Though I have stumbled several times over the usage of ‘resources’, I
haven’t found a single place, which would explain the usage of all
parameters (such as path_names:) and examples of usage. Right now, when
I really want to know how something is done in Rails, I google for it,
hoping that someone else had the same problem. This often works out, but
I would be more happy if I had a documentation of the Rails classes and
methods, in a similar way as it is for Ruby and the standard functions
and -classes. Is this available, or is Rails in the flux so much that we
can’t expect this yet?

On Tuesday, May 27, 2014 2:36:53 AM UTC-4, Ruby-Forum.com User wrote:

user is going to see. The initial screen will present an entry form for

Maybe this mapping “web page” to “controller” is, from the onset, bad
design?


Posted via http://www.ruby-forum.com/.

Web pages would be more likely to map to a controller action, not to a
controller. It’s common to start by laying out your web pages and then
working back from there. However, I’ll warn you it’s usually a back and
forth process. Once you have the web pages laid out, you need to
establish
a structure that usually involves grouping pages to controllers that
follow
Rails conventions.

In this case, you have at least three resources: user, dict, and idiom.
You ultimately will most likely have more. I would recommend you go
through the tutorial at railstutorial.org because it does a very good
job
of introducing these concepts and you will really need to understand
this
when you introduce password authentication.

Editing a dict resource would not be adding and removing idioms, that
would
be the create and destroy actions of the idiom resource. Editing a dict
resource would involve renaming the dictionary or changing the
dictionary
type.

Rails comes with a default set of actions related to a resource but you
don’t have to use all of them. It’s also not a perfect science. A good
example is your training screens. That might be its own resource, it
might
just be an extension of the idiom resource, or it could be its own
controller but not correspond to a resource. It depends on how much
functionality there is. Not everything will fit into a resource. For
example, many applications have static pages such as a home page, an
“about
us” page, etc. I usually group those into a pages controller which
stands
on its own, it has no resource or model behind it. Again, the tutorial
will do a much better job of explaining this.

On Wednesday, May 28, 2014 2:55:59 AM UTC-4, Ruby-Forum.com User wrote:


Posted via http://www.ruby-forum.com/.

When you get to the point where you are going to use password
authentication, re-read the user authentication part of the tutorial.
Right now, you have login mapped to an index action. Actually, login
uses
the concept of a session resource and you create a session when you log
in.
You will want to understand that concept and how a session store is
used
to maintain security.

Good Luck.

Thank you for the suggestions. I went through the tutorial found on the
web (which was explaining the concepts using the example of making a
blog site), but could relate what I have learned, only to the concept of
the idioms in my project, but not to the rest of my application.

I now see that is a good idea to treat the user as its own resource,
because sooner or later I will need this anyway, and I will try to
redesign my application.

mike2r wrote in post #1147433:

On Wednesday, May 28, 2014 2:55:59 AM UTC-4, Ruby-Forum.com User wrote:


Posted via http://www.ruby-forum.com/.

When you get to the point where you are going to use password
authentication, re-read the user authentication part of the tutorial.

Thanks, I will do so. I already started to read the tutorial you
recommended, and I must say it’s really well written!

Ronald