2013-11-14 18 views
6

Caso:utente con amichevole ID

mie forme stazione contengono un campo slug, se viene inserito un valore che deve essere utilizzato come la lumaca.

EDIT: qualche chiarimento:

Quello che voglio è molto simile a come lumache lavorano in wordpress:

  • Se non viene fornito alcun slug -> slug il nome
  • Se viene fornito slug -> utilizzare la lumaca utente immesso
  • Se slug viene aggiornato -> spingere vecchia lumaca alla storia

Il mio problema:

Non riesco a capire come ottenere Friendly Id per utilizzare lo slug fornito dall'utente.

class Station < ActiveRecord::Base 
    extend FriendlyId 
    belongs_to :user 
    has_many :measures 
    validates_uniqueness_of :hw_id 
    validates_presence_of :hw_id 
    class_attribute :zone_class 
    self.zone_class ||= Timezone::Zone 
    friendly_id :name, :use => [:slugged, :history] 

    before_save :set_timezone! 

    .... 

    def should_generate_new_friendly_id? 
    name_changed? or slug_changed? 
    end 
end 

edit:

<%= form_for(@station) do |f| %> 

<%= 
    f.div_field_with_label(:name) do |key| 
     f.text_field(key) 
    end 
%> 
<%= 
    f.div_field_with_label(:slug) do |key| 
     f.text_field(key) 
    end 
%> 
<%= 
    f.div_field_with_label(:hw_id, 'Hardware ID') do |key| 
     f.text_field(key) 
    end 
%> 
<%= 
    f.div_field_with_label(:latitude) do |key| 
     f.text_field(key) 
    end 
%> 
<%= 
    f.div_field_with_label(:longitude) do |key| 
     f.text_field(key) 
    end 
%> 
<%= f.div_field_with_label(:user_id, "Owner") do |key| 
     f.select(:user_id, options_from_collection_for_select(User.all, :id, :email), { include_blank: true }) 
    end 
%> 

    <div class="actions"> 
    <%= f.submit %> 
    </div> 
<% end %><%= form_for(@station) do |f| %> 

<%= 
    f.div_field_with_label(:name) do |key| 
     f.text_field(key) 
    end 
%> 
<%= 
    f.div_field_with_label(:slug) do |key| 
     f.text_field(key) 
    end 
%> 
<%= 
    f.div_field_with_label(:hw_id, 'Hardware ID') do |key| 
     f.text_field(key) 
    end 
%> 
<%= 
    f.div_field_with_label(:latitude) do |key| 
     f.text_field(key) 
    end 
%> 
<%= 
    f.div_field_with_label(:longitude) do |key| 
     f.text_field(key) 
    end 
%> 
<%= f.div_field_with_label(:user_id, "Owner") do |key| 
     f.select(:user_id, options_from_collection_for_select(User.all, :id, :email), { include_blank: true }) 
    end 
%> 

    <div class="actions"> 
    <%= f.submit %> 
    </div> 
<% end %> 
+0

Puoi mostrare il modulo? In questo momento stai usando il nome per friendly_id. Tutto quello che dovresti fare è consentire all'utente di cambiare il parametro del nome. – ChrisBarthol

+0

L'utente può modificare già il parametro name - quello che voglio è che l'utente sia in grado di personalizzare lo slug - ma l'app dovrebbe generare una lumaca in base al nome se non viene fornita nessuna lumaca – max

+0

Immagino di essere confuso da cosa stai chiedendo L'utente può cambiare il nome, quindi possono personalizzare lo slug. Se vuoi lo slug generato da un parametro diverso avresti semplicemente 'friendly_id: parameter,: use => [: slugged,: history]' – ChrisBarthol

risposta

4

questo è come mi risolto:

class Station < ActiveRecord::Base 
    extend FriendlyId 
    belongs_to :user 
    has_many :measures 
    validates_uniqueness_of :hw_id 
    validates_presence_of :hw_id 
    class_attribute :zone_class 
    self.zone_class ||= Timezone::Zone 
    friendly_id :name, :use => [:slugged, :history] 
    before_save :evaluate_slug 
    before_save :set_timezone! 


    def should_generate_new_friendly_id? 
    if !slug? 
     name_changed? 
    else 
     false 
    end 
    end 

end 

E prove:

/spec/models/station_spec.rb

describe Station do 
    ... 
    let(:station) { create(:station) } 

    describe "slugging" do 
    it "should slug name in absence of a slug" do 
     station = create(:station, name: 'foo') 
     expect(station.slug).to eq 'foo' 
    end 

    it "should use slug if provided" do 
     station = create(:station, name: 'foo', slug: 'bar') 
     expect(station.slug).to eq 'bar' 
    end 
    end 
    ... 
end 

/spec/controllers/stations_controller.rb

describe StationsController do 

    ... 

    describe "POST create" do 
     it "creates a station with a custom slug" do 
      valid_attributes[:slug] = 'custom_slug' 
      post :create, {:station => valid_attributes} 
      get :show, id: 'custom_slug' 
      expect(response).to be_success 
     end 

     ... 
    end 

    describe "PUT update" do 
     it "updates the slug" do 
      put :update, {:id => station.to_param, :station => { slug: 'custom_slug' }} 
      get :show, id: 'custom_slug' 
      expect(response).to be_success 
     end 

     ... 
    end 

    ... 
end 
+0

Cosa succede se c'è un conflitto? Come se l'utente fornisse una lumaca già in uso? – mscriven

+0

@mscriven, per impostazione predefinita, friendly-id lo risolverà rendendo unico lo slug aggiungendo un hash come "foo-cdeea311-1957-4fab-b649-dd2a2b9ad90d".Penso che potresti usare 'validates_uniqueness_of: slug' se vuoi applicarlo con le convalide di Active Record. – max

1

Per cambiare quale parametro viene utilizzato come la lumaca è sufficiente modificare il parametro friendly_id:

class Station < ActiveRecord::Base 
    extend FriendlyId 
    belongs_to :user 
    has_many :measures 
    validates_uniqueness_of :hw_id 
    validates_presence_of :hw_id 
    class_attribute :zone_class 
    self.zone_class ||= Timezone::Zone 
    friendly_id :SLUGNAME, :use => [:slugged, :history] 

    before_save :set_timezone! 

    .... 

    def should_generate_new_friendly_id? 
    name_changed? or SLUGNAME_changed? 
    end 
end 

Quindi secondo lei semplicemente un modo per l'utente di modificare il slugname, seguendo il tuo punto di vista:

<%= 
    f.div_field_with_label(:SLUGNAME) do |key| 
    f.text_field(key) 
    end 
%> 
+0

Scusa se non sono riuscito a spiegare, ma questo mi è mancato. Grazie mille per il tuo impegno! – max

Problemi correlati