开发者

Rails - How to differentiate an action call from different pages?

I have a destroy action defined for a particular resource. On completion, it uses an rjs file with a visual effect to remove the resource from the page that it is being called 开发者_如何学运维from.

My problem is that the destroy action can be called from 2 different templates. And so the visual effect needs to be different, depending on which template it is being called from... Is there a way to do so...?

1: I figure that one way I could do this, is to have a destroy action, and a destroy-variant action, with one template calling the destroy-variant action, and the other calling the normal one... However, I'm pretty sure that that is against the idea of DRY. And to be honest, I'm not entirely sure how to do so either... Will using :method => :delete, :action => :destroy-variant in the URL options work?

2: The other way that seems like a possibility to me, is to find out which page is calling the action, and then pushing out different rjs files as appropriate. But I've got absolutely no idea how to differentiate which page is doing the action calling.

3: The final way is just for me to redo the templates/RJS so that the same visual effect can be applied to both templates.

I'd appreciate the advice! :)


You do not mention the javascript library that you are using. This solution is jquery based. Its quite easy to do what you want using just one action destroy. But i would suggest a different technique to go about it. I find rjs pretty constraining. Go for the jquery taconite plugin. Its all markup rather than... a bunch of javascript mixed with erb which is less appealing to the eyes!

So now instead of your destroy.rjs you will have a destroy.xml.erb. Before i go into what you need to put in it, lets see what modifications you need to make for your destroy action.

BEFORE:

   def destroy
        @model = Model.find(params[:id])
        @model.destroy

          respond_to do |format|
            format.html { redirect_to :action => :index }
            format.xml
          end
    end

AFTER:

   def destroy
        @model = Model.find(params[:id])
        @model.destroy
        @template = params[:template]
          respond_to do |format|
            format.html { redirect_to :action => :index }
            format.xml
          end
    end

Add a named route in your routes.rb to simplify things:

map.destroy_using_template 'destroy/:id/:template', :controller => "controller", :action => "destroy"

In your views:

Add the jquery taconite plugin to the header in your <layout>.html.erb,

<%= javascript_include_tag "jquery.js", "jquery.taconite.js" %>

In the view for template 1:

Assuming you use a link to delete.

   <%= link_to "Delete", destroy_using_template_path(:id => "1", :template => "temp1"), :method => :delete, :confirm => "Are you sure you want to delete the record?" %>

and the same for template 2:

Assuming you use a link to delete.

   <%= link_to "Delete", destroy_using_template_path(:id => "1", :template => "temp2"), :method => :delete, :confirm => "Are you sure you want to delete the record?" %>

Now in your destroy.xml.erb

<taconite>
    <% if @template=="temp1" %>
      <remove select="#template1" />
    <% elsif @template=="temp2" %>
      <remove select="#template2" />
    <% end %>

    <eval>
        //OPTIONAL: Execute some javascript here if you want. You can do most of the DOM modifications using taconite itself.
        alert("HEY!!!");
    </eval>
</taconite>

Is it not easy now? :)

Remember, while using taconite you have to make sure the code in destroy.xml.erb is XML compliant. Make sure you close any open tags. Read up more on taconite here: http://malsup.com/jquery/taconite/

Taconite implements all the regular jquery DOM modifiers in markup and a few extra of its own. If you want to switch to javascript you can easily do so by just including that javascript in the eval tag as shown above.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜